我正在尝试在Hibernate中映射双向(一对多和多对一)关系。我们在尝试保存结果时遇到错误。
我们得到的错误是:
引起:org.hibernate.PropertyValueException:not-null属性引用null或transient值:com.example.Component.resultId 在org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:92)
从下面的源代码中,Result
可以包含多个Component
个,Component
个Result
可以属于单个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>
答案 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 ,然后保存组件