使用Hibernate映射多对多关联时,将额外的属性添加到中间表中 [英] Add extra property to intermediary table when mapping many-to-many association with Hibernate

查看:255
本文介绍了使用Hibernate映射多对多关联时,将额外的属性添加到中间表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在数据库中,我有以下三个表,其中 User Profile 具有多对多关系,并且加入 User_Profile 如下:

  User User_Profile配置文件
---- ------------ -------
user_id user_id profile_id
user_name profile_id profile_description
user_time

Class UserHbm ProfileHbm 使用:

  @Entity 
@Table(name =User)
public class UserHbm {

@Id
@GeneratedValue(generator =id-generator)
@GenericGenerator(name =id-generator,
strategy =com。 xx.xxx.XXXSequenceGenerator,
参数= {@Parameter(name =sequenceName,value =User)})
@Column(name =user_id)
private long用户名;

@Column
private String user_name;

@Column
私人日期user_time;

@ManyToMany(cascade = CascadeType.REFRESH,fetch = FetchType.EAGER)
@JoinTable(name =User_Profile,
joinColumns = {@JoinColumn(name =identityProfileID )},
inverseJoinColumns = {@ JoinColumn(name =profile_id)})
private Set< ProfileHbm> profiles = new HashSet< ProfileHbm>();

//不相关的其他代码

}

@Entity
@Table(name =Profile)
public class ProfileHbm {

@Id
@GeneratedValue(generator =id-generator)
@GenericGenerator(name =id-generator,
strategy = com.xx.xxx.XXXSequenceGenerator,
parameters = {@Parameter(name =sequenceName,value =Profile)})
@Column(name =profile_id)
私人长profile_id;

@Column
private String profile_description;

//不相关的其他代码

}

到目前为止,一切都很好,直到出现新的需求:将 user_time 放入 User_Profile 中,以使模式看起来像:

  User User_Profile配置文件
---- ------------ - -----
user_id user_id profile_id
user_name profile_id profile_description
user_time user_time

任何人都可以告诉我如何做到这一点?



我是否需要创建另一个中介 HBM 要做到这一点?

解决方案

解决方案是为UserProfile连接表创建一个新实体。设置一个从用户实体到新的UserProfile实体的OneToMany关系,以及从Profile到User_Profile的OneToMany。

你必须创建一个adda l class,假设UserProfilePk为由user_id和profile_id组成的组合索引的User_Profile实体。

$ pre
$ @
$ public class UserProfilePk {
@ManyToOne
private User

@ManyToOne
私人资料
}

然后,您必须将该类用于User_Profile索引:

  @Entity 
public class UserProfile {
@EmbeddedId
私人UserProfilePk pk;

@Column(name =user_time)
private user userTime;


你的课程User:

  @Entity 
public class User {
@Id
private Long id;

私人字符串名称;

私人日期userTime;

@OneToMany(mappedBy =pk.user,cascade = CascadeType.ALL)
private Set< UserProfile>的UserProfiles;
}

和课程档案:


  @Entity 
public class Profile {
@Id
private Long id;

私人字符串描述;

@OneToMany(mappedBy =pk.profile)
private Set< UserProfile>的UserProfiles;
}

下面的代码保存用户和关联的配置文件: p>

  Configuration configuration = new Configuration(); 
configuration.configure(hibernate.cfg.xml);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()。applySettings(configuration.getProperties())。build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.getCurrentSession();

User user = new User();
user.setId(1l);
user.setName(Scott);
user.setUserTime(new Date());
档案档案=新档案();
profile.setId(1l);
profile.setDescription(some user);

Transaction tx = session.beginTransaction();
session.save(profile);

UserProfilePk pk = new UserProfilePk();
pk.setProfile(profile);
pk.setUser(user);

UserProfile userProfile = new UserProfile();
userProfile.setPk(pk);
userProfile.setUserTime(new Date());

设置< UserProfile> ups = new HashSet<>();
ups.add(userProfile);
user.setUserProfiles(ups);

session.save(user);
tx.commit();


In database, I have following three tables, where User and Profile have many-to-many relationship and joined with User_Profile as follow:

User                User_Profile            Profile
----                ------------            ------- 
user_id             user_id                 profile_id
user_name           profile_id              profile_description
user_time

Class UserHbm and ProfileHbm are used:

@Entity
@Table(name = "User")
public class UserHbm {

    @Id
    @GeneratedValue(generator = "id-generator")
    @GenericGenerator(name = "id-generator",
            strategy = "com.xx.xxx.XXXSequenceGenerator", 
            parameters = { @Parameter(name = "sequenceName", value = "User") })
    @Column(name = "user_id")
    private long user_id;   

    @Column
    private String user_name; 

    @Column
    private Date user_time; 

    @ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinTable(name="User_Profile", 
            joinColumns = { @JoinColumn(name = "identityProfileID") },
            inverseJoinColumns={@JoinColumn(name="profile_id")})
    private Set<ProfileHbm> profiles = new HashSet<ProfileHbm>();

    //irrelevant other codes

}

@Entity
@Table(name = "Profile")
public class ProfileHbm {

    @Id
    @GeneratedValue(generator = "id-generator")
    @GenericGenerator(name = "id-generator",
            strategy = "com.xx.xxx.XXXSequenceGenerator", 
            parameters = { @Parameter(name = "sequenceName", value = "Profile") })
    @Column(name = "profile_id")
    private long profile_id;    

    @Column 
    private String profile_description;   

    //irrelevant other codes

}

So far, everything is fine until a new requirement comes up: put user_time into User_Profile so that the schema looks like:

User                User_Profile            Profile
----                ------------            ------- 
user_id             user_id                 profile_id
user_name           profile_id              profile_description
user_time           user_time

Could anyone could show me how to achieve this?

Do I have to create another intermediary HBM to do this?

解决方案

A solution is to create a new entity for UserProfile join table.
Set a OneToMany relationship from User entity to new UserProfile entity and a OneToMany from Profile to User_Profile.
You will have to create an additional class, let say UserProfilePk, for the User_Profile entity for the composite index composed of user_id and profile_id.

@Embeddable
public class UserProfilePk {
  @ManyToOne
  private User

  @ManyToOne
  private Profile
}

Then you have to use that class for the User_Profile index:

@Entity
public class UserProfile {
  @EmbeddedId
  private UserProfilePk pk;

  @Column(name = "user_time")
  private Date userTime;

}

Your class User:

@Entity
public class User {
  @Id
  private Long id;

  private String name;

  private Date userTime;

  @OneToMany(mappedBy = "pk.user", cascade=CascadeType.ALL)
  private Set<UserProfile> userProfiles;
}

And the class Profile:

@Entity
public class Profile {
  @Id
  private Long id;

  private String description;

  @OneToMany(mappedBy = "pk.profile")
  private Set<UserProfile> userProfiles;
}

And here below the code to save a User and an associated Profile:

Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.getCurrentSession();

User user = new User();
user.setId(1l);
user.setName("Scott");
user.setUserTime(new Date());
Profile profile = new Profile();
profile.setId(1l);
profile.setDescription("some user");

Transaction tx = session.beginTransaction();     
session.save(profile);

UserProfilePk pk = new UserProfilePk();
pk.setProfile(profile);
pk.setUser(user);

UserProfile userProfile = new UserProfile();
userProfile.setPk(pk);
userProfile.setUserTime(new Date());

Set<UserProfile> ups = new HashSet<>();
ups.add(userProfile);    
user.setUserProfiles(ups);

session.save(user);
tx.commit();

这篇关于使用Hibernate映射多对多关联时,将额外的属性添加到中间表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆