【问题标题】:Violation of foreign key constraint JPA违反外键约束JPA
【发布时间】:2014-11-11 10:07:13
【问题描述】:

编辑:这段代码实际上可以正常工作。这个问题是不相关的,是由于一个冲突的实体正在创建一个外键约束并阻止我插入到 DataFile 表中。

对于简单的@OneToMany 映射,我在使用一些 JPA 映射时遇到了一些真正的问题。

我正在使用 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;
}

数据文件.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() { }
}

这是@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;  
    }
}

问题是,当我使用一些 DataFile 对象创建一个 Study2 对象并尝试将其持久保存到我的数据库时,我得到了错误

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

如果我更改 getDataFiles() 上的注释并删除 @JoinColumn(见下文),则映射有效,但是它会创建一个连接表,我真的宁愿在 DataFile 表中有一个连接列:

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

我想这取决于我的@IdEntityBaseItem 中,因为当我删除它并在Study2 类中添加@Id 然后它按预期工作,但是必须有一些方法来保留@Id EntityBaseItem 仍然使用@JoinColumn?我的代码中的其他地方没有任何问题,而且我还有其他各种映射,它们不像这个那么简单。

我知道错误的含义,但我不知道为什么会这样。对我来说,我希望我的代码能够工作并自动级联 DataFiles,并为每个文件添加一个新的 id。

下面是实际引发错误的代码:

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

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

我将其简化为用于测试,在 .commit() 上抛出错误,然后回滚提交。

【问题讨论】:

  • 你的映射错误。不可能在 List 上提供 @JoinColumn 说 Study2 类在一行中保存 DataList 表的许多键
  • @ShoaibChikate 如果是这样的话,如果不是 List 应该是什么?
  • 我添加了答案。请检查
  • 导致此异常的代码在哪里。什么是外键约束 DATAFILE_STUDY_ID?
  • 我没有解释。对我来说,这也应该有效。但我对 EclipseLink 没有任何经验。如果我必须了解问题出在哪里,我会阅读生成的 SQL 查询,并查看有问题的外键约束的定义。

标签: java jpa derby


【解决方案1】:

更改您的映射

public class Study2(){

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

这里我们说DataFile是由DataFile类中的“study2”映射的,Study2有JoinColumn。而且Study2是关系的反面,更新时不会更新关系。

在DataFile中添加一个字段Study2,我已经在字段上给出了映射。您可以更改它

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

它表明许多 DataFile 存在于一个 Study2 类中

【讨论】:

  • 这是完全错误的。 OneToMany 单向关联上的 JoinColumn 非常好。见docs.oracle.com/javaee/6/api/javax/persistence/JoinColumn.html
  • 是的,没关系,除非我们有 JoinTable。 OP 没有连接表。
  • 没有。再次阅读 javadoc。它说“使用外键映射”。它还说:“连接列在订单表中”。要将关联与连接表映射,请使用 JoinTable。要将关联与连接列映射,请使用 JoinColumn。这不合逻辑吗?
  • 我同意并更改我的答案。但是映射很好。 OP 说“如果我更改 getDataFiles() 上的注释并删除 @JoinColumn (见下文),那么映射就可以工作,但是它会创建一个连接表,我真的宁愿在 DataFile 表中有一个连接列。”
  • 因此要在 DataFile 表中有 join 列,我们需要在 DataFile 类中有 Study2 字段,它将是 JoinColumn
猜你喜欢
  • 1970-01-01
  • 2021-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 2018-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多