在使用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
类型属性的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类代码by clicking on this link 您可以阅读整个堆栈跟踪by clicking on this link Here is a link到BaseEntity类的代码。
答案 0 :(得分:1)
改变这个:
@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;
我认为您必须将“change_this_with_primary_key_variable_name_from_HL7DocumentEntity”更改为“id”,就像它在BaseEntity中一样,但是看看你的sql表,你会看到正确的名称。
我希望你注意我告诉JPA如何使用相同的“Link_Documents”表来链接这两个表。我认为这是你的错误。只需确保使用正确的变量名称更改我告诉您的位置,我认为它应该可以正常工作
答案 1 :(得分:-3)
你知道我会从清理这段代码开始。
虽然hibernate文档可能会告诉你将这些注释放在字段变量上是好的,但它作为一个标准是一个坏主意。字段级别要求hibernate在延迟提取的情况下可以访问字段之前创建代理。所以,只要习惯正确地做到这一点,你就不会有发现问题的不幸。将所有这些注释移动到getter,因为属性级别访问不需要代理。
字段级变量应该是私有的。
你正在向那里的一个整数施放一个整数......其中一些东西让我不想看它,如实地说这可能是一种愚蠢的懒惰,最终成为你的问题。
当你在它时,继续用新的HashSet(0)初始化集合;像这样的东西。还是破了更新我们。