简体   繁体   English

违反外键约束JPA

[英]Violation of foreign key constraint JPA

Edit: This code actually works correctly. 编辑:此代码实际上正常工作。 The problem was un-related and was due to a conflicting Entity which was creating a foreign key constraint and stopping me from inserting into the DataFile table. 这个问题是无关的,并且是由于冲突的Entity正在创建外键约束并阻止我将其插入DataFile表。

I'm having some real trouble with some JPA mappings for a simple @OneToMany mapping. 我在使用一些简单的@OneToMany映射的JPA映射时遇到了一些麻烦。

I'm using EclipseLink and DerbyDB. 我正在使用EclipseLink和DerbyDB。

@Entity( name = "study2" )
@Access( AccessType.FIELD )
public class Study2 extends EntityBaseItem {

private List<DataFile> datafiles = new ArrayList<DataFile>();

public Study2() { }

@OneToMany( cascade = CascadeType.ALL, orphanRemoval = true )
@JoinColumn( name="STUDY_ID", referencedColumnName = "ID" )
@Access( AccessType.PROPERTY )
public List<DataFile> getDatafiles() {
    return this.datafiles;
}

public void setDatafiles( List<DataFile> dfList ) {
    this.datafiles = dfList;
}

DataFile.java 数据文件

@Entity( name = "DataFile" )
public class DataFile extends EntityBaseItem<DataFile> {
    private String filename;
    private long filesize;
    private String fileStatus;
    private String fileType;
    private String fileSubType;

    public DataFile() { }
}

This is my EntityBaseItem.java where the @Id resides: 这是@Id所在的我的EntityBaseItem.java:

@MappedSuperclass
public abstract class EntityBaseItem {

    @Id
    @GeneratedValue( strategy = GenerationType.TABLE )  
    protected Integer id;

    protected EntityBaseItem() {}

    public Integer getId() {
        return id;
    }

    public void setId( Integer id ) {
        this.id = id;
    }

    @Override  
    public int hashCode() {  
        int hash = 0;  
        hash += ( this.getId() != null ? this.getId().hashCode() : 0);  

        return hash;  
    }  

    @Override  
    public boolean equals(Object object) {  
        if (this == object)  
            return true;  
        if (object == null)  
            return false;  
        if (getClass() != object.getClass())  
            return false;  

        EntityBaseItem other = (EntityBaseItem)object;  

        if (this.getId() != other.getId() && (this.getId() == null || !this.id.equals(other.id))){  
            return false;  
        }

        return true;  
    }
}

The problem is that when I create a Study2 object with some DataFile objects and try to persist it to my DB then I get the error 问题是,当我创建带有一些DataFile对象的Study2对象并尝试将其持久保存到数据库时,我得到了错误

UPDATE on table 'DATAFILE' caused a violation of foreign key constraint 'DATAFILE_STUDY_ID' for key

If I change the annotation on getDataFiles() and remove the @JoinColumn ( see below ) then the mapping works, however it creates a join table and I'd really rather just have a join column in the DataFile table: 如果我更改getDataFiles()上的注释并删除@JoinColumn (请参见下文),则该映射有效,但是它创建了一个@JoinColumn表,而我实际上只希望在DataFile表中有一个联接列:

@OneToMany( cascade = CascadeType.ALL, orphanRemoval = true )
@Access( AccessType.PROPERTY )
public List<DataFile> getDatafiles() {
    return this.datafiles;
}

I guess it's down to having my @Id in EntityBaseItem as when I removed that and added @Id in the Study2 class then it worked as expected, however there must be some way to keep @Id in the EntityBaseItem and still use a @JoinColumn ? 我想这是因为我将@Id放在EntityBaseItem是,当我删除@Id并将其添加到Study2类中之后,它才按预期工作,但是必须有某种方法将@Id保留在EntityBaseItem并且仍然使用@JoinColumn吗? I've not had any issues elsewhere in my code, and I have various other mappings which are not as simple as this one. 我的代码中的其他地方都没有任何问题,而且还有其他各种映射,这些映射不像此映射那么简单。

I know what the error means, however I don't know why it's happening. 我知道错误的含义,但是我不知道为什么会发生。 To me I'd expect my code to work and cascade the DataFiles automatically with a new id for each. 对我来说,我希望我的代码能够正常工作,并自动为DataFiles层叠一个新的ID。

Here is the code that actually causes the error to be thrown: 这是实际上导致引发错误的代码:

Study2 testStudy = new Study2();
// set some datafiles etc.

EntityManager em = getEM(); // gives me EntityManager
em.getTransaction().begin();
em.persist( testStudy );
em.getTransaction().commit();

I'd simplified it down to that for testing, throws error on .commit() and then it rolls back the commit. 我将其简化为测试,在.commit()上引发错误,然后回滚提交。

Change your mappings 更改您的映射

public class Study2(){

@OneToMany( cascade = CascadeType.ALL, orphanRemoval = true,mappedBy="study2")
@Access( AccessType.PROPERTY )
public List<DataFile> getDatafiles() {
    return this.datafiles;
}
}

Here we say that DataFile is mappedBy "study2" in DataFile class and Study2 has JoinColumn. 在这里,我们说DataFile是通过DataFile类中的“ study2”映射的,而Study2具有JoinColumn。 And the Study2 is inverse side of relationship and will not update the relationship when it gets updated. 而且Study2是关系的反面,并且在关系更新时不会更新关系。

Add one field Study2 in DataFile, I have given mapping on field.You can change that 在DataFile中添加一个字段Study2,我已经在字段上指定了映射。您可以更改

   @ManyToOne
   @JoinColumn(name="STUDY_ID", referencedColumnName = "ID")
   private Study2 study2;

It states that many DataFile are present in one Study2 class 它指出在一个Study2类中存在许多DataFile

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM