1

Currently I have a child entity that has a @ManyToOne association to it's parent entity. Previous developers have set this field as lazy="false" to get the parent whenever needed when the session is closed too, however I decided it should be lazy="true" as it's not always used but when doing so I ran into LazyInitializationException because the session is closed and the child is detached from the session when it tries to get the parent.

I was wondering if it's right to move some more logic of the run method as seen bellow to the service class which interacts with DAOs thus I could avoid the exception because currently the service classes are like plain classes which have the needed DAOs injected and they just call the DAO method and returns the result. Should I put like more methods in the service class which interact with the entities, which would get the user and check everything for log in action, get parent if needed and then just return the log in result to run method..

public class Login extends Runnable {
     private UserService userService;
     ...
     public void run() {
         ...
         User user = userSerivce.getById(id);
         Account account = user.getAccount(); //LazyInitializationException
         ...
         if (account.isLocked()) {
             ...
         }
         ...
         userService.save(user);

         //Send some message to the user..
     }
}

public class UserServiceImpl implements UserService {
    private UserDAO userDAO;
    ...
    public User getById(long id) {
        return userDAO.getById(id);
    }
    public void save(User user) {
        userDAO.save(user);
    }
}

public UserDAOImpl implements UserDAO {
    private SessionFactory factory;
    ...
    public User getById(long id) {
        return (User) factory.getCurrentSession().load(User.class, id);
    }
    public void save(User user) {
        factory.getCurrentSession().saveOrUpdate(user);
    }
}

I use Spring's <tx:advice> to handle the closing and other transaction related stuff.

Rihards
  • 10,241
  • 14
  • 58
  • 78
  • What interface do you have? A web interface? Or a remote client? – Puce Jun 23 '11 at 16:21
  • 1
    What is that run method? I can't understand you very well but I think the work should be done in the service layer so if it has an associated DB session it may get data from lazy associations. If you don't want to do that for any reason you may force the initialization of the lazy field when the session is open and use it later. In hibernate you can do that with ´Hibernate.initialize(myBean.getMyLazyValue());´ – aalku Jun 23 '11 at 16:21
  • Note the second paragraph is not clear. We don't know how your code looks like... – Puce Jun 23 '11 at 16:22
  • Sorry guys, added code example! Hope it makes sense now. – Rihards Jun 23 '11 at 16:29
  • @Puce, it's not a web application, no. It's like game server. – Rihards Jun 23 '11 at 16:32

2 Answers2

3

I prefer to have all of my entity relationships as lazy since I don't know if and when I'll need those external entities. This way I can avoid unnecessary joins when I don't need the additional entities. If I do end up needing the entity I create a named query and eager fetch the entity or collection. Here's an example.

I do agree though that you should be sending a DTO instead of the entity back to your calling front end application. Hibernate entities are full of proxies and it would be inefficient to send them back. I'm not really sure if you are sending these objects to a jsp/velocity/etc file or to an external application but I would recommend using a DTO if you are sending back JSON or something similar to the calling application. Here's another question that deals with DTO's click here that discusses 2 frameworks for easy conversion.

Community
  • 1
  • 1
telm
  • 472
  • 3
  • 6
  • Nope, not sending those anywhere. They just stay in there and user gets response with the needed stuff transferred in string from the entity. Thanks tho. – Rihards Jun 23 '11 at 19:21
0

Create DTOs, don't send JPA Entities over the net.

When you create the DTOs, you will have to access the required properties, what will trigger to load them.

Puce
  • 37,247
  • 13
  • 80
  • 152
  • I don't send the entities over net(work). Hmm, can you give some example of `DTO`s ? – Rihards Jun 23 '11 at 16:42
  • The question is: are the server and client running in the same JVM? If not use a DTO – Puce Jun 23 '11 at 17:02
  • Yea, they are.. It's a socket server and the end user is in Flash player. – Rihards Jun 23 '11 at 17:05
  • A DTO is the client view of your data and is usually independent of any server-side persistence mechanism. It's a design pattern. You can look it up. – Puce Jun 23 '11 at 17:06