映射双向一对多休眠实体

时间:2017-08-11 09:30:41

标签: java spring hibernate jpa spring-jdbc

我正在尝试在Hibernate中映射双向(一对多和多对一)关系。我们在尝试保存结果时遇到错误。

我们得到的错误是:

  

引起:org.hibernate.PropertyValueException:not-null属性引用null或transient值:com.example.Component.resultId       在org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:92)

从下面的源代码中,Result可以包含多个Component个,ComponentResult可以属于单个resultId。其中一项要求是Result 中的String必须@Entity @Table(name = "result") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public abstract class Result extends AbstractEntity { @OneToMany(cascade = CascadeType.MERGE) @JoinColumn(name = "resultId") private List<Component> component = new ArrayList<>(); } @Entity @Table(name = "cmpt") @XmlRootElement public class Component extends AbstractEntity { @ManyToOne(targetEntity = Result.class) private String resultId; } 。这个要求超出了我们的控制范围。

示例实体源代码如下:

@Entity
@Table(name = "result")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Result extends AbstractEntity {

    @OneToMany(cascade = CascadeType.MERGE, nullable = false)
    @JoinColumn(name = "resultId")
    private List<Component> component = new ArrayList<>();
}

@Entity
@Table(name = "cmpt")
@XmlRootElement
public class Component extends AbstractEntity {
    @Column(name = "result_id", insertable = false, updatable = false, nullable = false)
    private String resultId;
}

以下是适合我的解决方案

[ts] <error message>

2 个答案:

答案 0 :(得分:1)

创建双向实体的正确方法是这样做。

@Entity
@Table(name = "result")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Result extends AbstractEntity {

    @OneToMany(cascade = CascadeType.MERGE, mappedBy="result")
    private List<Component> component = new ArrayList<>();
}

@Entity
@Table(name = "cmpt")
@XmlRootElement
public class Component extends AbstractEntity {
    @ManyToOne(targetEntity = Result.class)
    @JoinColumn(name = "result_id")  //result_id is the column name (foreign key) in cmpt table
    private Result result;

    @Column(name = "result_id", insertable = false, updatable = false)
    private String resultId;
}

这将确保只有一个双向关系(不是两个单向关系等)。如果您有其他想法,请告诉我。

更新1:

您可以按照上面的说明向实体添加其他密钥。您将获得外键作为字符串。但您需要记住,不应删除使用JoinColumn的实际映射。我测试了上面的配置,它似乎对我有用。

答案 1 :(得分:0)

我认为您必须从 Component.java 类中删除注释@ManyToOne(targetEntity = Result.class),当您首先尝试保存数据时,必须使用save保存结果方法,然后你通过save方法返回 resultId ,使用setter和getter在组件实体中设置此 resultId ,然后保存组件