约束违反时坚持一对多关系 [英] Constraint Violation when persisting One To Many relation

查看:160
本文介绍了约束违反时坚持一对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用hibernate和MySQL的spring mvc应用程序中,我收到了以下违反约束的异常:

  .mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
无法添加或更新子行:外键约束失败
(`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 {

//其他属性

@ManyToOne
@JoinColumns({@JoinColumn(name =ptcode,referencedColumnName =code),
@JoinColumn( name =ptcodesystem,referencedColumnName =codesystem)
})
private HL7GeneralCode providertype;

// getters and setters
}

这是 GeneralCode class:

  @Entity 
@Table =hl7_generalcodes)
public class HL7GeneralCode implements Serializable {

private static final long serialVersionUID = -8620565054475096516L;

@EmbeddedId
私人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.clinicService.savehl7DocumentEntity(mydent);
} else {
//其他东西
}

是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不是持久的。我们不支持
抛出新的IllegalStateException(不能使用非持久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);如果(de.getId()== null){
System.out.println([[[[[[[关于持久化]]] ]]]]]]]]]]]]]]]]]);
em.persist(de);
} else {
System.out.println(]]]]]]]]]]]]]]]]]]合并de [[[[[[[[[ [[[[[[[[[[[);
de = em.merge(de);





执行的SQL语句和hibernate试图通过sql插入的实际值是:

  [[[[[[[about插入到hl7_documententity(author_id,authpar_id,entitytype,id_extension,id_root,ptcode,ptcodesystem,id)插入到hl7_documententity(插入到hl7_documententity中)。值(?,?,?,?,?,?,?,?)
Hibernate:insert into hl7_documententity(author_id,authpar_id,entitytype,id_extension,id_root,ptcode,ptcodesystem,id)values(?,? ?,?,?,?,?,?)
TRACE BasicBinder - 绑定参数[1]为[INTEGER] - < null>
TRACE BasicBinder - 绑定参数[2]为[INTEGER] - < null>
TRACE BasicBinder - 作为[VARCHAR]的绑定参数[3] - < null>
TRACE BasicBinder - 绑定参数[4] as [VARCHAR] - NI
TRACE BasicBinder - 绑定参数[5] as [VARCHAR] - nullFlavor
TRACE BasicBinder - 绑定参数[6] as [ VARCHAR] - UNK
TRACE BasicBinder - 绑定参数[7] as [VARCHAR] - HL7NullFlavor
TRACE BasicBinder - 绑定参数[8] as [INTEGER] - 32787
WARN SqlExceptionHelper - SQL错误: 1452,SQLState:23000
错误SqlExceptionHelper - 无法添加或更新子行:外键约束失败(`docbd`.`hl7_documententity`,CONSTRAINT`hl7_documententity_ibfk_1` FOREIGN KEY(`ptcode`,`ptcodesystem`)参考`hl7_generalcode`(`code`,`codesystem`))
INFO AbstractBatchImpl - HHH000010:在批量发布时,它仍包含JDBC语句
WARN警告 - 处理程序执行导致异常

您可以阅读EmbedCodePK类代码 by cli cking on this link

您可以阅读整个堆栈跟踪通过点击此链接

这是一个链接代码为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 =codePk)})
private HL7GeneralCode providertype;

我认为您必须将change_this_with_primary_key_variable_name_from_HL7DocumentEntity更改为id,就像它在BaseEntity中一样,看看你的SQL表,你会看到正确的名称。



我希望你注意到我如何让JPA使用相同的Link_Documents表来链接2个表。我认为这是你的错误。只要确保改变我告诉你的正确的变量名称,我认为它应该可以工作

In a spring mvc application using hibernate and MySQL, I am getting the following constraint violation exception:

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`))

The problem occurs when I try to save a DocumentEntity containing a property of type GeneralCode, both of which are defined below.

I have read many postings and blogs on this error, but none seem to resolve my problem. How can I resolve this error?

Here is the DocumentEntity class:

@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    
}

Here is the GeneralCode class:

@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    
}

Here is the code from the controller:

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
}

Here is the dao method:

@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);
        }
    }
}

The executed SQL statement and the actual values that hibernate is trying to insert via the sql are:

[[[[[[[[[[[[ 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

You can read the EmbedCodePK class code by clicking on this link.
You can read the entire stack trace by clicking on this link.
Here is a link to the code for the BaseEntity class.

解决方案

Change this:

@OneToMany(mappedBy = "providertype")
private Set<HL7DocumentEntity> documententities;

To this:

@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;

And in HL7DocumentEntity change as follows:

This

@ManyToOne
    @JoinColumns({ @JoinColumn(name = "ptcode", referencedColumnName = "code"),
        @JoinColumn(name = "ptcodesystem", referencedColumnName = "codesystem")
    })
    private HL7GeneralCode providertype;

Change to this:

@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;

I think you have to change "change_this_with_primary_key_variable_name_from_HL7DocumentEntity" with "id" like it is in BaseEntity but take a look at your sql table, you willsee there the correct name.

I hope you notice How I told JPA to use the same "Link_Documents" table for linking the 2 tables. I think this is were your mistake is. Just make sure to change where I told you with the correct variable name and I think it should work

这篇关于约束违反时坚持一对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆