Having a hard time getting a simple OneToMany mapped by the ManyToOne Entity to work when I go to fetch a user's comments. Other answers have suggested that you have to create the query yourself with the entityManager but that seems so horrible. Whats the point of an ORM if you can't even do something simple like this without hardcoding inline sql? Seems more likely that I'm doing something wrong.
Seems like maybe it has something to do with the fact that I'm accessing the user.getComments() method from jsp using the model. Not sure what the best way to do this is.
Schema:
CREATE TABLE users (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE comments (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
comment_text VARCHAR(255) NOT NULL,
photo_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(user_id) REFERENCES users(id)
);
User Controller method:
@RequestMapping("/user")
public ModelAndView getUser(@RequestParam int id) {
return new ModelAndView("user", "message", userService.getUser(id));
}
UserService:
@Service
public class UserService {
private UserDAO userDAO;
@Autowired
public UserService(UserDAO userDAO) {
this.userDAO = userDAO;
}
@Transactional
public User getUser(int id) {
return userDAO.getUser(id);
}
}
UserDAO:
@Repository
public class UserDAO {
@PersistenceContext
EntityManager entityManager;
@Nullable
public User getUser(int id)
{
return entityManager.find(User.class, id);
}
}
User entity:
@Entity
@Table(name="users")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="username")
private String userName;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="created_at")
private Date createdAt;
@OneToMany(mappedBy="user")
private List<Comment> comments;
public int getId() {
return id;
}
public String getUserName() {
return userName;
}
public Date getCreatedAt() {
return createdAt;
}
@Transactional
public List<Comment> getComments() {
return comments;
}
}
Comment entity:
@Entity
@Table(name="comments")
public class Comment {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="comment_text")
private String commentText;
@Column(name="photo_id")
private int photoId;
@ManyToOne
@JoinColumn(name="user_id")
private User user;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at")
private Date createdAt;
@Override
public String toString() {
return "Comment [id=" + id + ", commentText=" + commentText + ", photoId=" + photoId + ", userId=" + user.getId()
+ ", createdAt=" + createdAt + "]";
}
public int getId() {
return id;
}
public String getCommentText() {
return commentText;
}
public int getPhotoId() {
return photoId;
}
public User getUser() {
return user;
}
public Date getCreatedAt() {
return createdAt;
}
}
Stacktrace:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/test] threw exception [An exception occurred processing [WEB-INF/jsp/user.jsp] at line [34]
31: User 32: Creation date 33: 34: 35: 36: 37:
Stacktrace:] with root cause org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.instagramviewer.entity.User.comments, could not initialize proxy - no Session at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:602) at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:217) at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:581) at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:148) at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:303) at org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator(ForEachSupport.java:348) at org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator(ForEachSupport.java:224) at org.apache.taglibs.standard.tag.common.core.ForEachSupport.prepare(ForEachSupport.java:155) at javax.servlet.jsp.jstl.core.LoopTagSupport.doStartTag(LoopTagSupport.java:256) at org.apache.jsp.WEB_002dINF.jsp.user_jsp._jspx_meth_c_005fforEach_005f0(user_jsp.java:285) at org.apache.jsp.WEB_002dINF.jsp.user_jsp._jspService(user_jsp.java:172) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:170) at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1370) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1116) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)
@OneToMany(mappedBy="user",fetch = FetchType.LAZY)` and in@ManyToOne(fetch = FetchType.LAZY)`. - SRy