在使用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_documententity_ibfk_1` FOREIGN KEY (`ptcode`, `ptcodesystem`) REFERENCES `hl7_generalcode` (`code`, `codesystem`))
当我尝试保存一个DocumentEntity包含type的属性时,会出现问题GeneralCode,这两个属性都在下面定义。
DocumentEntity
GeneralCode
我已经读过很多关于此错误的帖子和博客,但似乎没有一个可以解决我的问题。 如何解决此错误?
这是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 }
这是GeneralCode课程:
@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 }
这是来自控制器的代码:
HL7GeneralCode authcode = processGeneralCode(grandkid); HL7GeneralCode testcode = this.clinicService.findGeneralCodeByPK(authcode.getCodePk().getCode(), authcode.getCodePk().getCodesystem()); if(testcode==null){ authcode.addDocumententity(mydent); this.clinicService.savehl7GeneralCode(authcode); mydent.setProvidertype(authcode); //this next line throws the error this.clinicService.savehl7DocumentEntity(mydent); }else{ //other stuff }
这是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); } } }
已执行的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
您可以通过单击此链接阅读EmbedCodePK类代码。 您可以通过单击此链接来读取整个堆栈跟踪。 这是 BaseEntity类代码的链接。
更改此:
@OneToMany(mappedBy = "providertype") private Set<HL7DocumentEntity> documententities;
对此:
@OneToMany(fetch = FetchType.LAZY) @JoinTable(name = "Link_Documents", joinColumns = {@JoinColumn(name = "codePk", unique = true)}, inverseJoinColumns = {@JoinColumn(name = "change_this_with_primary_key_variable_name_from_HL7DocumentEntity")}) private Set<HL7DocumentEntity> documententities;
并在HL7DocumentEntity中进行如下更改:
这个
@ManyToOne @JoinColumns({ @JoinColumn(name = "ptcode", referencedColumnName = "code"), @JoinColumn(name = "ptcodesystem", referencedColumnName = "codesystem") }) private HL7GeneralCode providertype;
更改为此:
@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;
我认为您必须像在BaseEntity中那样将“ change_this_with_primary_key_variable_name_from_HL7DocumentEntity”更改为“ id”,但请看一下您的sql表,您将看到正确的名称。
希望您注意到我如何告诉JPA如何使用相同的“ Link_Documents”表链接两个表。我认为这是您的错误。只要确保使用正确的变量名更改我告诉您的位置,我认为它应该可以工作