2015-08-09 98 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您想反映這種變化的實體。
相關問題