2015-08-09 89 views
0

我们有2个具有@ManyToOne关系的实体。JPA insertable = false updatable = false id创建时未更新

当我们在@Transactional方法中创建一个EntityB实例entityAld(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

你是如何坚持'EntityB'与'EntityA'关联的?请编辑答案以添加代码。如果您使用其构造函数创建entityB并传递了entityA,那么发布的第一个代码片段应该可以工作,所以我认为问题与逻辑和事务有关。另一个评论是,如果你没有设置正确的'entityAId'值,你发布的第二个代码将不会保持关系。 – Guillermo

回答

0

要更新id字段,需要该对象的持续操作。默认情况下,当持续对象EntityB时,entityA字段中的对象不会自动保留。

我看到了两个可能的解决方案:

A)使用cascade

@ManyToOne(optional = true, fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST}) 
private EntityA entityA; 

(或使用CascadeType.ALL

B)坚持entityA手动

entityManager.persist(entityA); 
+0

感谢您的回答,在我们创建entityB之前entityA已经被持久保存到数据库的情况下也是这种情况(在不同的事务中) – Ayelet

0

对我来说,你的映射看起来不正确。 @ManyToOne或实体之间定义的任何其他关联,但您已在entityAId上定义它。理想情况下,它应该是实体(在这里您应该使用insertable = false updatable = false),并且您应该在其上定义单独的字段entityAId@column。现在你应该自己更新这个领域。

如果你想处理冬眠删除insertable = false updatable = false

+0

谢谢,请参阅我的编辑:我尝试了您的解决方案,并且ID仍为空。 。 – Ayelet

1

休眠不会“对飞”(当你改变一些其他领域或相似)填充实体领域。它也不会在persist/flush上执行(例外是一些特殊的字段,如id和版本)。

从数据库中提取实体实例时会填充不可插入/不可更新的字段。所以,做出这样的字段初始化/由Hibernate在您执行修改它们映射到基础列相同的事务刷新,你应该先冲洗会话,然后:

  1. 清晰的会话,并重新 - 读取实体;
  2. refresh您想反映这种变化的实体。
相关问题