This week's book giveaway is in the Agile and Other Processes forum.
We're giving away four copies of The Little Book of Impediments (e-book only) and have Tom Perry on-line!
See this thread for details.
Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

IndirectList: not instantiated when trying to recover a object from database-ManytoMany relationship

 
Jrcastro Ribeiro
Greenhorn
Posts: 29
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi again (so many topics with my name hehe, sorry for bothering so much).

The problem is:

I have a Many to Many relationship: my class ordemservico has many objects from the layoutsos class


But a need to get that list of layouts to edit one ordemservico.

Thats what im doing:



And here is my ManytoMany table, as you can see, i have a lot of ID's from OrdemServico corresponding to Many layouts.


http://i.imgur.com/ifmY7Tv.png

I can get everything of the specif Ordemservico, but when I do a getLayoutsosList() the returns is:





Edit, im using that native method from JPA:
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First of all, do you really have a public instance variable? That's often a bad practice. One of the main principles of a good object-oriented design is encapsulation.

Jrcastro Ribeiro wrote:I can get everything of the specif Ordemservico, but when I do a getLayoutsosList() the returns is:


Probably because OneToMany and ManyToMany relationships are lazy by default in JPA. So when you get your entity (using the findOrdemservico() method) only basic types are populated with values from the database (e.g id, name, dates,...), but not the collections because those might require very complex queries and might result in poor performance. You should definitely read the Lazy Fetching section of the Java Persistence WikiBook.

You'll probably have to retrieve your layouts in the same transaction as the one you are using to retrieve the Ordemservico from the database. And you can do it in your entity mapping by using a different fetch type. But remember then this list will be always retrieved from the database, even when you are only interested in the id, name and some dates (resulting in poor performance). Or you can simply access the list of layouts in the same transaction by calling the getLayoutsosList() method.

Hope it helps!
Kind regards,
Roel
 
Jrcastro Ribeiro
Greenhorn
Posts: 29
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote:First of all, do you really have a public instance variable? That's often a bad practice. One of the main principles of a good object-oriented design is encapsulation.

Jrcastro Ribeiro wrote:I can get everything of the specif Ordemservico, but when I do a getLayoutsosList() the returns is:


Probably because OneToMany and ManyToMany relationships are lazy by default in JPA. So when you get your entity (using the findOrdemservico() method) only basic types are populated with values from the database (e.g id, name, dates,...), but not the collections because those might require very complex queries and might result in poor performance. You should definitely read the Lazy Fetching section of the Java Persistence WikiBook.

You'll probably have to retrieve your layouts in the same transaction as the one you are using to retrieve the Ordemservico from the database. And you can do it in your entity mapping by using a different fetch type. But remember then this list will be always retrieved from the database, even when you are only interested in the id, name and some dates (resulting in poor performance). Or you can simply access the list of layouts in the same transaction by calling the getLayoutsosList() method.

Hope it helps!
Kind regards,
Roel


First of all, do you really have a public instance variable? That's often a bad practice.


yYou're absolutely right.
when a finish a class I usually review everything to find errors, thank you to show me that!



Here is my entity mapping: if i understanding, i need to change or add the (fetch=FetchType.LAZY) annotation ?




Or you can simply access the list of layouts in the same transaction by calling the getLayoutsosList() method.


what you meant by access the list of layouts in the same transaction? really seems to be the best solution
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jrcastro Ribeiro wrote:Here is my entity mapping: if i understanding, i need to change or add the (fetch=FetchType.LAZY) annotation ?

Adding fetch=FetchType.LAZY won't make any difference, because that's already the default, so JPA is already using it. If you want the list of layouts to be fetched together with the entity, you need to add fetch=FetchType.EAGER instead. But remember, if you set the fetch type to EAGER, each and every time you get an Ordemservico entity from the database, the list of layouts will be retrieved as well. This might result in poor performance of your application (because you might only need the id, name and a few dates; not a list of 100 layouts).

Jrcastro Ribeiro wrote:what you meant by access the list of layouts in the same transaction? really seems to be the best solution

It's reall simple. You have to make sure the list of layouts is retrieved from the database. But it has to happen in the same transaction as retrieving the entity. So you might end something like thisAnd then you can use the list of layouts in your application.

Hope it helps!
Kind regards,
Roel
 
Jrcastro Ribeiro
Greenhorn
Posts: 29
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote:
Jrcastro Ribeiro wrote:Here is my entity mapping: if i understanding, i need to change or add the (fetch=FetchType.LAZY) annotation ?

Adding fetch=FetchType.LAZY won't make any difference, because that's already the default, so JPA is already using it. If you want the list of layouts to be fetched together with the entity, you need to add fetch=FetchType.EAGER instead. But remember, if you set the fetch type to EAGER, each and every time you get an Ordemservico entity from the database, the list of layouts will be retrieved as well. This might result in poor performance of your application (because you might only need the id, name and a few dates; not a list of 100 layouts).

Jrcastro Ribeiro wrote:what you meant by access the list of layouts in the same transaction? really seems to be the best solution

It's reall simple. You have to make sure the list of layouts is retrieved from the database. But it has to happen in the same transaction as retrieving the entity. So you might end something like thisAnd then you can use the list of layouts in your application.

Hope it helps!
Kind regards,
Roel


Hi Roel, thank you again for the support!

And im back to show my solution.

That's what i have done:




And here is the method to find the LayoutsosList:



Don't know if was the best solution, certainly have better, but that work for me. =)
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jrcastro Ribeiro wrote:Hi Roel, thank you again for the support!

You are welcome!

Jrcastro Ribeiro wrote:And im back to show my solution.

Glad to hear you were able to solve your issue again. And thanks for sharing!

Jrcastro Ribeiro wrote:Don't know if was the best solution, certainly have better, but that work for me. =)

With your current setup (opening and closing the transaction in the findOrdemservico() method), it's probably the best possible solution. But I wonder if you won't get in trouble in the (near) future. Because you'll probably need to have transactions on a higher level (e.g. a business service method which updates two or three entities in one transaction).

If you would have the transaction on a higher level, this code will also populate the list with layouts

Kind regards,
Roel
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic