Leo*_*rak 11 java hibernate jpa java-ee
我在JPA实体中有延迟加载属性的问题.我读了许多类似的问题,但它们与spring或hibernate有关,它们的问题不适用或有用.
该应用程序是JEE,在Wildfly应用程序服务器上运行JPA2.1.有两个实体,DAO会话bean和servlet将它们组合在一起:
@Entity
@Table(name = "base_user")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
int id;
@OneToMany(fetch=FetchType.LAZY, mappedBy="user")
List<OAuthLogin> oauthLogins;
}
@Entity
@Table(name = "oauth_login")
public class OAuthLogin implements Serializable {
@ManyToOne
@JoinColumn(name="user_id", nullable=false)
User user;
}
@Stateless(name = "UserDAOEJB")
public class UserDAO {
@PersistenceContext(unitName="OAUTHDEMO")
EntityManager em;
public User findById(int id) {
User entity;
entity = em.find(User.class, id);
return entity;
}
}
public class SaveUserServlet extends HttpServlet {
@EJB
UserDAO userDAO;
@Transactional
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
User user = new User(name);
user.setEmail(email);
System.out.println("Persisting user " + user);
userDAO.persist(user);
OAuthLogin fbLogin1 = new OAuthLogin(user, OAuthProvider.FACEBOOK, "1501791394");
loginDAO.persist(fbLogin1);
User user2 = userDAO.findById(user.getId());
List<OAuthLogin> oauthLogins = user2.getOauthLogins();
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,它失败了:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: cz.literak.demo.oauth.model.entity.User.oauthLogins, could not initialize proxy - no Session
org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:572)
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:212)
org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:551)
org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:140)
org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:294)
cz.literak.demo.oauth.servlets.SaveUserServlet.doPost(SaveUserServlet.java:66)
Run Code Online (Sandbox Code Playgroud)
我使用了与WebLogic/JPA1非常相似的模式,并且运行顺畅.任何的想法?谢谢
PS.这是一个JPA应用程序,我没有hibernate会话等.
Ori*_*Dar 15
您可以使用的替代品很少:
@OneToMany(fetch=FetchType.LAZY, mappedBy="user", cascade = {CascadeType.PERSIST})
List<OAuthLogin> oauthLogins;
Run Code Online (Sandbox Code Playgroud)
在你的Servlet中:
User user = new User(name);
user.setEmail(email);
OAuthLogin fbLogin = new OAuthLogin(user, OAuthProvider.FACEBOOK, "1501791394");
user.getOauthLogins().add(fbLogin) // this is enough assuming uni-directional association
userDAO.persist(user);
List<OAuthLogin> oauthLogins = user.getOauthLogins();
Run Code Online (Sandbox Code Playgroud)
这应该做,而且你有一个事务和更少的JDBC调用.
这对于特定Servlet方法调用的特定用例很有帮助.
public User findById(int id, boolean prefetch) {
User entity = em.find(User.class, id);
if (prefetch) {
// Will trigger 1 or size JDBC calls depending on your fetching strategy
entity.getOauthLogins().size()
}
return entity;
}
Run Code Online (Sandbox Code Playgroud)
或者,使用条件覆盖提取模式
这对于您希望在保留a时获取OAuthLogin集合的每个案例都很有用,并且仅针对该特定集合进行避免. UserFetchType.LAZYLazyInitializationException
只要谷歌它,你会发现很多例子
对于LazyInitializationException跨越每个实体应用程序而言,这将基本上阻止每个懒惰地获取的关联
PS:
@Transactional(默认情况下甚至不适用HttpServlet)| 归档时间: |
|
| 查看次数: |
50387 次 |
| 最近记录: |