我们有2个具有@ManyToOne关系的实体。
当我们在@Transactional方法中创建EntityB的实例时,entityAId(insertable = false updatable = false)不会自动更新 - 即使entityA实例已经持久化了。
有解决方法吗?我们是否必须在ctor中手动更新它?
@Entity
public class EntityA {
@Id
@GeneratedValue
private Long id;
public EntityA() {
super();
}
...
}
@Entity
public class EntityB {
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional = true, fetch = FetchType.LAZY)
private EntityA entityA;
@Column(name = "entityA_id", insertable = false, updatable = false)
private Long entityAId;
public EntityB() {
super();
}
public EntityB(EntityA entityA) {
super();
this.entityA = EntityA;
}
...
}
编辑:还尝试了以下内容,但事务中仍然是entityAId = null(即使entityA之前已经保留)。
@Entity
public class EntityB {
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "entityA_id", insertable = false, updatable = false)
private EntityA entityA;
@Column(name = "entityA_id")
private Long entityAId;
...
}
答案 0 :(得分:1)
Hibernate不会在实时填充实体字段' (当你改变其他一些领域或类似的时候)。它也不会在persist / flush上执行它(例外是一些特殊字段,如id和version)。
从DB中获取实体实例时,将填充不可插入/不可更新的字段。因此,要使Hibernate在同一事务中初始化/刷新这些字段,在该事务中对其映射到的基础列执行更改,您应首先刷新会话,然后执行以下任一操作:
答案 1 :(得分:0)
要更新id
字段,需要对象的持久操作。默认情况下,持久保存entityA
对象时,字段EntityB
中的对象不会自动保留。
我看到两种可能的解决方案:
A)使用cascade
@ManyToOne(optional = true, fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
private EntityA entityA;
(或使用CascadeType.ALL
)
B)手动持续entityA
entityManager.persist(entityA);
答案 2 :(得分:0)
对我来说,你的映射看起来并不合适。 @ManyToOne
或实体之间定义的任何其他关联,但您已在entityAId
上对其进行了定义。理想情况下,它应该是实体(在这里您应该使用insertable = false updatable = false
),并且您应该在其上定义单独的字段entityAId
并定义@column
。现在你应该自己更新这个字段。
如果你想要处理hibernate,请删除insertable = false updatable = false