欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hibernate JPA —— could not insert 或 detach entity passed to persist 或Found shared references 错误

程序员文章站 2022-04-16 08:52:43
...

错误一:

Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: 
[com.fsnip.tms.core.template.model.Template],

detach entity passed to persist错误。

分析:

检查主键生成策略,判断级联增加的数据列是否满足定义的条件,如非空等。(即两点:映射是否正确;插入的数据或级联插入的数据的各列是否满足约束,如非空等)。

如果是自动生成主键值(如自增主键),persistent方法前应该设置id为null。

此外,如果定义与数据库里面的bigint 类型对应的实体属性的数据类型为Long 类型,则该值没有默认值(即使数据库中指定了默认值),插入数据前必须判断其是否为null,为null则设置一个默认值0L。否则会出现类似错误:ERROR org.hibernate.util.JDBCExceptionReporter - Column 'ISREADONLY' cannot be null



错误二:

Found shared references to a collection

分析:

出现此错误的原因是实体的关联关系的集合不能共享(即使为空)。如下假设:

Teacher 实体与Student 实体为关联关系,且Teacher 与 Student为一对多关系,用Hibernate JPA 在实体类中通过集合体现如下:

1、映射Student 实体中的外键列TEACHER_ID:(省去getter、setter方法)

@ManyToOne(cascade={CascadeType.REFRESH,CascadeType.DETACH},optional=false, fetch = FetchType.LAZY)
@JoinColumn(name="TEACHER_ID")
private Teacher teacher;
说明:CascadeType.REFRESH 指定当参考的Teacher 实体刷新时,该Student 实体对象获取的其Teacher 对象自动刷新;optional=false 指定TEACHER_ID 在教师表中必须存在;@ManyToOne声明为多对一关系。

2、在Teacher 实体中定义Student 集合:(省去getter、setter方法)

@OneToMany(cascade={CascadeType.REMOVE},fetch=FetchType.LAZY,mappedBy="teacher")
private Set<Student> students = new HashSet<Student>();
经过以上定义后,当我在程序中通过需要复制一个Teacher 实体对象时,不能共享其students集合:

Template temp = old;//假设old是通过JPA 获取的
Teacher newT = new Teacher();
//修改相关信息后将新的Teacher 对象插入数据库
newT.setId(null);//假设主键自增
newT.setStudents(temp.getStduents());//执行此语句时不会出错,但再次查找此newT 或 old 时将提示错误二。
//正确做法
newT.setStudents(null);
//如果需为newT增加原来的students 集合数据,则只能通过JPA 将Student集合数据插入数据库(因为第2步中只定义了REMOVE级联操作)

















相关标签: jpa 错误