开发者

multiple ManyToOne in JPA: updating/creating references

(I'm a newbie in JPA) I have 3 JPA entities: User, Setting and UserSetting.

The relations are: ManyToOne between UserSetting, User; ManyToOne between UserSetting, Setting.

The purpose is: when adding an entry to UserSetting, an entry in Setting should be added only if it doesn't exist.

The question: I tried cascade=All in UserSetting on Setting, but it failed if a Setting already exist.

I can write multiple queries that add a Setting if it doesn't exist, then add UserSetting without the cascading to Setting table. But it doesn't sound reasonable. What is the acceptable way to do it in JPA?

Here is the code of entities:

    @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 = "Setting开发者_如何学运维EntitySeq", 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;
    }

}


To create a persistent UserSetting instance, you need a persistent Setting instance. Hibernate can't decide which instance it needs for you. You're responsible fo find a Setting instance, or create a new one, before setting it in the new UserSetting instance.


The answer I found was to manage UserSettingEntity via UserEntity: create/get SettingEntities, get UserEntity, add all its UserSettingEntities to User.settings and persist. That means for n settings, the number of queries = (2*n + 2)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜