在数据库中,我有三个表,其中User
和Profile
具有多对多关系,并与User_Profile
加入如下:
User User_Profile Profile
---- ------------ -------
user_id user_id profile_id
user_name profile_id profile_description
user_time
使用了类UserHbm
和ProfileHbm
:
@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
}
到目前为止,在出现新要求之前一切正常:将user_time
放入User_Profile
,以便架构如下所示:
User User_Profile Profile
---- ------------ -------
user_id user_id profile_id
user_name profile_id profile_description
user_time user_time
有人能告诉我如何实现这个目标吗?
我是否必须创建另一个中间人HBM
才能执行此操作?
答案 0 :(得分:1)
解决方案是为UserProfile连接表创建一个新实体
设置从User实体到新UserProfile实体的OneToMany关系以及从Profile到User_Profile的OneToMany。
您必须为User_Profile实体创建一个额外的类,比如UserProfilePk,用于由user_id和profile_id组成的复合索引。
@Embeddable
public class UserProfilePk {
@ManyToOne
private User
@ManyToOne
private Profile
}
然后你必须将该类用于User_Profile索引:
@Entity
public class UserProfile {
@EmbeddedId
private UserProfilePk pk;
@Column(name = "user_time")
private Date userTime;
}
您的班级用户:
@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;
}
班级简介:
@Entity
public class Profile {
@Id
private Long id;
private String description;
@OneToMany(mappedBy = "pk.profile")
private Set<UserProfile> userProfiles;
}
以下是保存用户和相关个人资料的代码:
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();
答案 1 :(得分:0)
如果您只需要在映射表中添加一个列,则只需更改UserHbm类即可。而不是:
@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>();
使用:
@ElementCollection
@JoinTable(name="User_profile")
@MapKeyJoinColumn(name="profile_id")
@Temporal(TemporalType.TIMESTAMP)
@Column(name="user_time")
private Map<Profile, Date> profiles = new HashMap<>();
当您需要在表格中添加更多列时,您甚至可以将地图的值更改为@Embeddable类。