JPA中的多个ManyToOne:更新/创建引用

时间:2011-04-14 08:28:24

标签: hibernate jpa

(我是JPA的新手) 我有3个JPA实体:用户,设置和用户设置。
关系是: UserSetting,User之间的ManyToOne; UserSetting,Setting。

之间的ManyToOne

目的是: 向UserSetting添加条目时,只有在不存在的情况下才应添加“设置”中的条目。

问题: 我在设置的UserSetting中尝试了cascade = All,但如果设置已经存在则失败。

如果不存在,我可以编写多个添加设置的查询,然后在没有级联到设置表的情况下添加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;
    }

}

2 个答案:

答案 0 :(得分:0)

要创建持久的UserSetting实例,您需要一个持久的Setting实例。 Hibernate无法决定它需要哪个实例。在新的UserSetting实例中设置实例之前,您有责任找到它,或者创建一个新实例。

答案 1 :(得分:0)

我找到的答案是通过UserEntity管理UserSettingEntity:create / get SettingEntities,获取UserEntity,将其所有UserSettingEntities添加到User.settings并保持不变。这意味着对于n个设置,查询数=(2 * n + 2)