2011-04-14 78 views
0

(我是JPA的新手) 我有3個JPA實體:User,Setting和UserSetting。
這些關係是: ManyToOne UserSetting,User;用戶設置,設置之間的ManyToOne。JPA中的多個ManyToOne:更新/創建引用

宗旨是: 增加UserSetting一個條目時,在設定的入口應添加只有當它不存在。

問題: 我嘗試cascade =所有在UserSetting上的設置,但它失敗了,如果一個設置已經存在。

我可以編寫多個添加設置的查詢(如果它不存在),然後添加UserSetting而不將級聯設置爲設置表。但這聽起來不合理。 在JPA中可以接受的方式是什麼?

這裏是實體代碼:

@Entity 
    @Table(name = "USERS", uniqueConstraints = @UniqueConstraint(columnNames = "USER_ID")) 
    @SequenceGenerator(name = "UserSeq", sequenceName = "USER_SEQ") 
    public class UserEntity { 
     private long id; 
     private Set<UserSettingEntity> settings; 

     public UserEntity() { 
     } 

     @Id 
     @GeneratedValue(strategy = GenerationType.AUTO, generator = "UserSeq") 
     @Column(name = "ID") 
     public long getId() { 
      return id; 
     } 

     public void setId(long id) { 
      this.id = id; 
     } 

     @Column(name = "SETTING") 
     @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) 
     public Set<UserSettingEntity> getSettings() { 
      if (settings == null) { 
       settings = new HashSet<UserSettingEntity>(); 
      } 
      return settings; 
     } 
    } 


    @Entity 
    @Table(name = "USER_SETTINGS", uniqueConstraints = @UniqueConstraint(columnNames = {"USER_ID", "SETTING_ID"})) 
    @SequenceGenerator(name = "UserSettingSeq", sequenceName = "USER_SETTING_SEQ") 
    public class UserSettingEntity { 

     private Long id; 
     private UserEntity user; 
     private SettingEntity setting; 
     private String value; 

     public UserSettingEntity() { 
     } 

     public UserSettingEntity(UserEntity user, SettingEntity setting, String value) { 
      this.user = user; 
      this.setting = setting; 
      this.value = value; 
     } 

     @Id 
     @GeneratedValue(strategy = GenerationType.AUTO, generator = "UserSettingSeq") 
     @Column(name = "ID") 
     public Long getId() { 
      return id; 
     } 

     public void setId(Long id) { 
      this.id = id; 
     } 

     @ManyToOne(cascade = CascadeType.ALL) 
     @JoinColumn(name = "USER_ID", nullable = false) 
     public UserConfigEntity getUser() { 
      return user; 
     } 

     public void setUser(UserConfigEntity user) { 
      this.user = user; 
     } 
     //if setting exists in database, dont try to add it again 
     @ManyToOne(cascade = CascadeType.REFRESH) 
     @JoinColumn(name = "SETTING_ID", nullable = false) 
     public SettingEntity getSetting() { 
      return setting; 
     } 
    public void setSetting(SettingEntity setting) { 
     this.setting = setting; 
    } 
    @Column(name = "VALUE") 
    public String getValue() { 
     return value; 
    } 

    public void setValue(String value) { 
     this.value = value; 
    } 
} 

@Entity 
@Table(name = "SETTING", uniqueConstraints = @UniqueConstraint(columnNames = {"CATEGORY", "CONTEXT", "NAME"})) 
@SequenceGenerator(name = "SettingEntitySeq", sequenceName = "SETTING_SEQ") 
public class SettingEntity { 

    private Long id; 
    private String name; 

... 

    public SettingEntity(String category, String name) { 
     this.name = name; 
    } 

    public SettingEntity() { 
    } 

    @Id 
    @Column(name = "SETTING_ID", nullable = false) 
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "SettingEntitySeq") 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

} 

回答

0

我發現的答案是通過UserEntity管理UserSettingEntity:創建/獲取SettingEntities,獲取UserEntity,將所有UserSettingEntities添加到User.settings並保留。這意味着對於n個設置,查詢數量=(2 * n + 2)

0

來創建一個持久UserSetting實例,需要一個持久的設置實例。 Hibernate無法決定它需要哪個實例。您需要負責查找Setting實例或創建一個新實例,然後將其設置在新的UserSetting實例中。

+0

感謝您的回答。這意味着當我有幾個UserSettings,並且我將需要4個查詢來添加一個UserSetting? (檢查設置是否存在,創建設置,檢查UserSetting是否存在,創建一個UserSetting) – lili 2011-04-14 12:30:12