bla*_*ard 0 java spring hibernate hibernate-mapping
我正试图从表中获取所有用户的电子邮件.实体用户:
@Entity
@Table(name = "tbl_User")
public class User {
@Expose
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
.....
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
List<CommunicationAddress> communicationAddresses = new ArrayList<CommunicationAddress>();
.....
}
Run Code Online (Sandbox Code Playgroud)
在服务中,我正在获取用户并尝试查看电子邮件:
User user = userDAO.getUserById(id);
if (user == null) {
throw new Exception("User not found");
} else {
List<Email> addresses = user.getCommunicationAddresses();
}
Run Code Online (Sandbox Code Playgroud)
但我收到了下一个例外:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:137)
at org.hibernate.collection.internal.PersistentBag.isEmpty(PersistentBag.java:249)
Run Code Online (Sandbox Code Playgroud)
获取用户的方法:
@Transactional
@Override
public User getUserById(Long userId) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(User.class);
criteria.add(Restrictions.eq("id", userId));
return (User) criteria.uniqueResult();
}
Run Code Online (Sandbox Code Playgroud)
我明白,当我让用户使用Criteria时,我必须得到沟通地址...怎么做?谢谢所有.
看来你的服务方法没有注释@Transactional.因此,在致电之后userDAO.getUserById(id);,不再有交易.这意味着您无法访问在事务中未访问/预先获取的已加载实体的任何延迟加载属性,而不会遇到LazyInitializationException.
因此,您可以考虑LAZY使用EAGER提取替换(这主要取决于您所面临的用例),或者您应该使用以下方法注释您的Service方法@Transactional.
我强烈建议您注释您的服务方法(而不是DAO方法),因为只有在与多个实体交互时才能建立有意义的事务边界.
此外,如果您使用延迟加载,您必须意识到在离开服务层后遇到这种异常的可能性,例如在渲染视图时(假设您以某种方式显示数据).
要触发延迟关联的即时加载(称为" 动态关联提取 "),请在以下位置添加以下行getUserById:
criteria.setFetchMode("communicationAddresses", FetchMoode.EAGER);
Run Code Online (Sandbox Code Playgroud)
但是,如果你在这个特定的方法中这样做,我想知道你为什么坚持懒加载?
| 归档时间: |
|
| 查看次数: |
4653 次 |
| 最近记录: |