自学Hibernate,我有以下表结构/关系
由以下类别表示......
@Entity
@Table(name = "users")
public class User implements IUser<Role>, Serializable {
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
@SequenceGenerator(name = "user_key_seq")
@Column(name = "key", insertable = false, updatable = false)
private Long key;
@Column(name = "name")
private String name;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name = "userroles",
joinColumns = {
@JoinColumn(name = "userkey")},
inverseJoinColumns = {
@JoinColumn(name = "rolekey")})
private Set<Role> roles = new HashSet<>(5);
@Override
public Set<Role> getRoles() {
return roles;
}
// Other setters and getters
}
@Entity
@Table(name = "roles")
public class Role implements IRole, Serializable {
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
@SequenceGenerator(name = "roles_key_seq")
@Column(name = "key", insertable = false, updatable = false)
private Long key;
@Column(name="name")
private String name;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="parentroles",
joinColumns = {@JoinColumn(name="childkey")},
inverseJoinColumns = {@JoinColumn(name="parentkey")})
private Set<Role> roles = new HashSet<>(5);
// Other setters and getters
}
我遇到的问题是......
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.kaizen.chishiki.core.data.User.roles, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180)
at og.kaizen.chishiki.core.testdatacore.Main.<init>(Main.java:37)
at og.kaizen.chishiki.core.testdatacore.Main.main(Main.java:25)
现在,我知道我可以将fetch
类型设置为FetchType.EAGER
,但除了性能问题之外,我不想这样做,我正试图了解这些问题;)
我想知道是否有办法编写Hibernate查询来满足这种关系并手动加载行(它还允许我返回Role
的接口,而不是我实现的实现现在要做(允许我维持合同))。
从我读过的内容来看,我似乎需要为Entity
构建一个UserRoles
。并不是说我反对这个解决方案,但我很好奇是否有办法绕过它。
roles
出现在许多其他关系中,因此它无法与父表形成直接关系(也就是说,我无法放置父表的key
直接在role
表中,users
可以有多个roles
)
我想到的另一个解决方案是编写一个存储过程来为我完成。虽然这是我可以解决的可行解决方案,但它确实使应用程序迁移到另一个数据库变得更加困难,而不是显示阻止,但我正在努力记住这些想法。
答案 0 :(得分:4)
如果要加载具有其角色的用户,但仍保持关联延迟,请使用包含left join fetch
的HQL查询:
select u from User u left join fetch u.roles where ...
如果您有用户并且想要在关闭会话之前确保其角色集合已初始化,请致电Hibernate.initialize(user.getRoles())
。
答案 1 :(得分:1)
如果您正在使用Hibernate 4.1.6+,那么可以通过在hibernate.properties中使用hibernate.enable_lazy_load_no_trans属性来处理这些延迟关联问题。
答案 2 :(得分:0)
我通过将控制器中的方法注释为transactional解决了这个问题。由于lazy-load基本上返回了未来对象的列表,因此该方法需要是事务性的。