Java 保持一对多关系时的约束冲突
在使用hibernate和MySQL的spring mvc应用程序中,我得到以下约束冲突异常:Java 保持一对多关系时的约束冲突,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,在使用hibernate和MySQL的spring mvc应用程序中,我得到以下约束冲突异常: Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`mybd`.`hl7_documententity`, CONSTRAINT `hl7_
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails
(`mybd`.`hl7_documententity`, CONSTRAINT `hl7_documententity_ibfk_1`
FOREIGN KEY (`ptcode`, `ptcodesystem`)
REFERENCES `hl7_generalcode` (`code`, `codesystem`))
当我试图保存一个包含GeneralCode
类型属性的DocumentEntity
时,就会出现问题,这两个属性的定义如下
我读过很多关于这个错误的帖子和博客,但似乎没有一个能解决我的问题如何解决此错误?
以下是DocumentEntity
类:
@Entity
@Table(name = "hl7_documententity")
public class HL7DocumentEntity extends BaseEntity{
//other properties
@ManyToOne
@JoinColumns({ @JoinColumn(name = "ptcode", referencedColumnName = "code"),
@JoinColumn(name = "ptcodesystem", referencedColumnName = "codesystem")
})
private HL7GeneralCode providertype;
//getters and setters
}
@Entity
@Table(name = "hl7_generalcodes")
public class HL7GeneralCode implements Serializable{
private static final long serialVersionUID = -8620565054475096516L;
@EmbeddedId
private HL7EmbedCodePK codePk;
@OneToMany(mappedBy = "providertype")
private Set<HL7DocumentEntity> documententities;
////////////getters and setters
}
以下是GeneralCode
类:
@Entity
@Table(name = "hl7_documententity")
public class HL7DocumentEntity extends BaseEntity{
//other properties
@ManyToOne
@JoinColumns({ @JoinColumn(name = "ptcode", referencedColumnName = "code"),
@JoinColumn(name = "ptcodesystem", referencedColumnName = "codesystem")
})
private HL7GeneralCode providertype;
//getters and setters
}
@Entity
@Table(name = "hl7_generalcodes")
public class HL7GeneralCode implements Serializable{
private static final long serialVersionUID = -8620565054475096516L;
@EmbeddedId
private HL7EmbedCodePK codePk;
@OneToMany(mappedBy = "providertype")
private Set<HL7DocumentEntity> documententities;
////////////getters and setters
}
以下是dao方法:
@Repository
public class JpaSomethingRepositoryImpl implements SomethingRepository {
@PersistenceContext
private EntityManager em;
@Override
@Transactional
public void savehl7DocumentEntity(HL7DocumentEntity de) {
HL7GeneralCode code = de.getProvidertype();
if(code !=null && code.getCodePk()==null){//HL7GeneralCode is not persistent. We don't support that
throw new IllegalStateException("Cannot persist an adress using a non persistent HL7GeneralCode");
}
System.out.println("=========================== inside jpaCdaRespository.saveDocEntity(de)");
de.setProvidertype(null);
if(code.getDocumententities()!=null){
ArrayList<HL7DocumentEntity> addrList = new ArrayList<HL7DocumentEntity>();
addrList.addAll(code.getDocumententities());
addrList.remove(de);
Set<HL7DocumentEntity> myaddrs = new HashSet<HL7DocumentEntity>(addrList);
code.setDocumententities(myaddrs);
}
code = em.merge(code);
de.setProvidertype(code);
code.addDocumententity(de);
if (de.getId() == null) {
System.out.println("[[[[[[[[[[[[ about to persist de ]]]]]]]]]]]]]]]]]]]]");
em.persist(de);
} else {
System.out.println("]]]]]]]]]]]]]]]]]] about to merge de [[[[[[[[[[[[[[[[[[[[[");
de = em.merge(de);
}
}
}
@存储库
公共类JpaSomethingRepositoryImpl实现了一些东西存储库{
@持久上下文
私人实体管理者;
@凌驾
@交易的
公共作废保存HL7DocumentEntity(HL7DocumentEntity de){
HL7GeneralCode代码=de.getProvidertype();
如果(code!=null&&code.getCodePk()==null){//HL7GeneralCode不是持久性的。我们不支持这一点
抛出新的非法状态异常(“无法使用非持久性HL7GeneralCode持久化地址”);
}
System.out.println(“===========================================内部jpaCdaRespository.saveDocEntity(de)”);
de.setProvidertype(空);
if(code.getDocumententities()!=null){
ArrayList addrList=新的ArrayList();
addrList.addAll(code.getDocumententities());
addrList.remove(de);
Set myaddrs=newhashset(addrList);
代码。setDocumententities(myaddrs);
}
代码=em.merge(代码);
de.setProvidertype(代码);
代码.addDocumententity(de);
if(de.getId()==null){
System.out.println(“[][][[][[][[D][T][[D][T][T][T][T][T][T][T][D][T][T][T][T][T][T][T][T][T][D][D][T][D][T][D][;
em.persist(de);
}否则{
System.out.println(“:/][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][;
de=em.merge(de);
}
}
}
执行的SQL语句和hibernate试图通过SQL插入的实际值为:
[[[[[[[[[[[[ about to persist de ]]]]]]]]]]]]]]]]]]]]
DEBUG SQL - insert into hl7_documententity (author_id, authpar_id, entitytype, id_extension, id_root, ptcode, ptcodesystem, id) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into hl7_documententity (author_id, authpar_id, entitytype, id_extension, id_root, ptcode, ptcodesystem, id) values (?, ?, ?, ?, ?, ?, ?, ?)
TRACE BasicBinder - binding parameter [1] as [INTEGER] - <null>
TRACE BasicBinder - binding parameter [2] as [INTEGER] - <null>
TRACE BasicBinder - binding parameter [3] as [VARCHAR] - <null>
TRACE BasicBinder - binding parameter [4] as [VARCHAR] - NI
TRACE BasicBinder - binding parameter [5] as [VARCHAR] - nullFlavor
TRACE BasicBinder - binding parameter [6] as [VARCHAR] - UNK
TRACE BasicBinder - binding parameter [7] as [VARCHAR] - HL7NullFlavor
TRACE BasicBinder - binding parameter [8] as [INTEGER] - 32787
WARN SqlExceptionHelper - SQL Error: 1452, SQLState: 23000
ERROR SqlExceptionHelper - Cannot add or update a child row: a foreign key constraint fails (`docbd`.`hl7_documententity`, CONSTRAINT `hl7_documententity_ibfk_1` FOREIGN KEY (`ptcode`, `ptcodesystem`) REFERENCES `hl7_generalcode` (`code`, `codesystem`))
INFO AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements
WARN warn - Handler execution resulted in exception
[][[][[][[][[de][]]]]]]]]]]]]]]]]]]]]]][[de][]]]]]]]]]]]]][[de][code][]]]]]]]]]]-[de][code][
调试SQL-插入hl7_documententity(author_id、authpar_id、entitytype、id_扩展、id_根、ptcode、ptcodesystem、id)值(?,,,,,,,,,?)
Hibernate:插入hl7_documententity(author_id、authpar_id、entitytype、id_扩展、id_根、ptcode、ptcodesystem、id)值(?,,,,,,,,,?)
跟踪BasicBinder-将参数[1]绑定为[INTEGER]-
跟踪BasicBinder-将参数[2]绑定为[INTEGER]-
TRACE BasicBinder-绑定参数[3]为[VARCHAR]-
TRACE BasicBinder-绑定参数[4]为[VARCHAR]-NI
跟踪BasicBinder-绑定参数[5]为[VARCHAR]-nullFlavor
TRACE BasicBinder-绑定参数[6]为[VARCHAR]-UNK
跟踪BasicBinder-绑定参数[7]为[VARCHAR]-HL7NullFlavor
跟踪BasicBinder-绑定参数[8]为[INTEGER]-32787
警告SqlExceptionHelper-SQL错误:1452,SQLState:23000
错误SqlExceptionHelper-无法添加或更新子行:外键约束失败(`docbd`.`hl7\u documententity`,约束`hl7\u documententity\u ibfk\u 1`外键(`ptcode`,`ptcodesystem`)引用`hl7\u generalcode`(`code`,`codesystem`)
InfoAbstractBatchImpl-hh000010:batch发布时,它仍然包含JDBC语句
警告-处理程序执行导致异常
您可以阅读EmbeddeCodePK类代码。您可以读取整个堆栈跟踪。
到BaseEntity类的代码。您知道,我将首先清理此代码 虽然hibernate文档可能会告诉您,将这些注释放在字段变量上是可以的,,,但作为一个标准,这不是一个好主意。字段级别要求hibernate在惰性抓取的情况下访问字段之前创建一个代理。因此,只要习惯于正确操作,您就不会不幸发现问题。全部移动那些作为属性级访问的getter注释不需要代理 字段级变量应该是私有的 你在那里把一个整数转换成一个整数…有些东西让我不想看它,老实说,可能会有一点愚蠢的懒惰,最终成为你的问题
当您正在使用时,继续使用新的HashSet(0)初始化集合;类似的事情。仍然会更新我们。您知道我将首先清理此代码 虽然hibernate文档可能会告诉您,将这些注释放在字段变量上是可以的,,,但作为一个标准,这不是一个好主意。字段级别要求hibernate在惰性抓取的情况下访问字段之前创建一个代理。因此,只要习惯于正确操作,您就不会不幸发现问题。全部移动那些作为属性级访问的getter注释不需要代理 字段级变量应该是私有的 你在那里把一个整数转换成一个整数…有些东西让我不想看它,老实说,可能会有一点愚蠢的懒惰,最终成为你的问题 当您使用新的HashSet(0)时,请继续初始化该集;类似的事情。仍然会更新我们。更改此项:
@OneToMany(mappedBy = "providertype")
private Set<HL7DocumentEntity> documententities;
更改为:
@ManyToOne(fetch = FetchType.LAZY)
@JoinTable(name = "Link_Documents", joinColumns = {@JoinColumn(name = "change_this_with_primary_key_variable_name_from_HL7DocumentEntity")}, inverseJoinColumns = {@JoinColumn(name = "codePk")})
private HL7GeneralCode providertype;
我认为您必须将“使用\u primary\u key\u variable\u name\u from\u HL7DocumentEntity”更改为“id”,就像在BaseEntity中一样,但看看您的sql表,您将看到正确的名称
我希望您注意到我是如何告诉JPA使用相同的“Link_Documents”表来链接这两个表的。我认为这是您的错误所在。请确保使用正确的变量名更改我告诉您的位置,我认为应该可以更改此项:
@OneToMany(mappedBy = "providertype")
private Set<HL7DocumentEntity> documententities;
更改为:
@ManyToOne(fetch = FetchType.LAZY)
@JoinTable(name = "Link_Documents", joinColumns = {@JoinColumn(name = "change_this_with_primary_key_variable_name_from_HL7DocumentEntity")}, inverseJoinColumns = {@JoinColumn(name = "codePk")})
private HL7GeneralCode providertype;
我认为您必须将“使用主关键字更改此变量名称”更改为“id”,就像在BaseEntity中一样,但要使用l