0

I am developing an application using Jboss AS 7, CDI, JPA, and some other resources bundled.

My question is: When I create a project in Eclipse using the maven-jboss-webapp-archetype it generates some files, which I have been extensively studying and trying to get along with. The problem is that sometimes I see myself a little bit confused whether I am using Hibernate resources or JPA resources.

Second question: When I use multiple @OneToMany relationships in the same Entity I notice two behaviors:

a) Without specifying EAGER type for Fetch, it deploys the application but when I try to use the list it gives me the LazyInitializationException error so vastly discussed here.

b) When I specify Eager for the FetchType on the @*ToMany relationship it just doesnt deploys the application. It gives me the error: Cannot instantiate multiple bags.

Here is the problematic piece of code:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "teamUser" , fetch = FetchType.EAGER)
private Collection<Users> usersCollection;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "teamRanking" , fetch = FetchType.LAZY)
private Collection<Ranking> rankingCollection;

@NotNull
@OneToMany(cascade = CascadeType.ALL, mappedBy = "teamModality" , fetch = FetchType.LAZY)
private Collection<Modality> modalitiesCollection;

public Teams() {

}

public Teams(Long id_team , String name) {
    this.id = id_team;
    this.name = name;
}

I have been reading about this and people told me that JPA does not support FetchType.EAGER for multiple realtionships in the same Entity. But I need to use multiple relationships in this entity in specific. I don't know what to do anymore, because I have tried several approaches, Lazy fetching, and all of them present some kind of issue. For example, if I leave only one FetchType.EAGER in the class then it deploys my app but it doesn't runs properly because when I try to fetch a List from the database it gives me the error: LazyInitializationException, and when I try to put all of them using the FetchType.EAGER it just doesnt deploy because it gives the error: Cannot instantiate multiple bags.

So my issues here are related to:

1) Maven-jboss-webapp-archetype uses hibernate or jpa or both? 2) How can I attack this problem of using multiple @OneToMany relationships in an Entity? And although I know that fetching eagerly the Collections in the model is not the best approach because when the system grows I will probably have performance issues right? So how can I properly work with Lazy loading?

musiKk
  • 14,751
  • 4
  • 55
  • 82
Arthur
  • 323
  • 4
  • 8
  • What JPA implementation are you using? Hibernate? – John Ament May 18 '13 at 18:41
  • Yes, I am using hibernate bundled in JBoss AS 7 which i think is Hibernate 4. Thanks for your answer John – Arthur May 18 '13 at 19:44
  • You should probably look at this SO for reference: http://stackoverflow.com/questions/10769656/how-to-use-jpa-2-0-manytomany-without-issues it uses Hibernate specific annotations, but can do what you need. – John Ament May 19 '13 at 14:15

1 Answers1

3

First of all, Hibernate is an implementation of the JPA pecification, and is the default one in JBoss. So you're using JPA, with Hibernate as the implementation.

Second, You get a LazyInitialization exception because you access a lazy-loaded collection, after having closed the session, without having initialized this collection while the session was still open. If you have two lazy collections and you know that the client code needs both initialized, initialize them before returning the entity and closing the session (i.e. while you're still inside the transactional service method):

SomeEntity e = em.find(SomeEntity.class, someId);
e.getFirstCollection().size(); // initialize the first collection
e.getSecondCollection().size(); // initialize the second collection
return e;

You can fetch multiple toMany associations at once, but only one of them can be a bag (i.e. a Collection or a List). I wouldn't advise eager collections generally. But if you really want them, make them Sets instead of Collections.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • JB Nizet Thank you very much for your explanation. That makes things a lot clearer. Can you take a look at one of my DAO methods? Because I dont know exactly what you mean by transactional service method. Because I am not using method such as commit or anything like that to retrieve data from the database. – Arthur May 18 '13 at 21:37
  • [code] public List retrieveAllMembersOrderedByName() { List teams = null; CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery criteria = cb.createQuery(Teams.class); Root member = criteria.from(Teams.class); criteria.select(member).orderBy(cb.asc(member.get(Member_.name))); criteria.select(member).orderBy(cb.asc(member.get("name"))); teams = em.createQuery(criteria).getResultList(); return teams; } – Arthur May 18 '13 at 21:42
  • Edit your question if youwant to add code. You MUST use transactions to access the entity manager. In a Java EE environment such as an app deployed on JBoss and using CDI, this is as simple as making a service class annotated with @Stateless, which makes it a session EJB. EJBs are transactional by default. – JB Nizet May 19 '13 at 08:04