Does JPA ( Eclipselink in this case) always return IndirectList where Entity have a List?
Is ok that list or It should be converted to another list( maybe linkedlist)?
Analysis
If we look at EclipseLink's IndirectList's API, it says:
To use an IndirectList: declare the appropriate instance variable with type IndirectList (jdk1.1) or Collection/List/Vector (jdk1.2).
TopLink will place an IndirectList in the instance variable when the
containing domain object is read from the datatabase. With the first
message sent to the IndirectList, the contents are fetched from the
database and normal Collection/List/Vector behavior is resumed.
If we view IndirectList sources, we will see, that all the work is delegated to it's original collection, just like API says.
Answers
Does JPA ( Eclipselink in this case) always return IndirectList where Entity have a List?
Yes, it always does return your specified collection wrapped with IndirectList. Since it delegates all its internal work to the wrapped collection, it preserves the way it works.
Is ok that list or It should be converted to another list( maybe
linkedlist)?
Yes, it is okay to use IndirectList. You don't convert, you just define any type of collection you want and don't worry about IndirectList, since it is managed transparently.
Since List is an interface the JPA provider is free to return any implementation. EclipseLink rerurns an IndirectList where a List is used. This is perfectly fine since the IndirectList is a List.
For the record or for future reference, it is generally best practice to use interfaces with JPA.
Related
We recently joined up to an existing project and in several entity classes we have seen the following code example:
#OneToMany(mappedBy = "department")
private List<Employee> employee= new LinkedList<>();
I had a discussion with a developer about using ArrayList instead of LinkedList for hibernate. But the arguments from both sides were not clear enough.
Usually, i use for many purposes an ArrayList. Here is a good comparison
Does hibernate under the hood work better with that?
Is there a reason why linkedList is used?
Or has it simply been used unknowingly in the project?
The actual implementation used when an entity is loaded from the database is not the same as the default value in the class definition. This is why entity properties which are collections must be specified as an interface type.
Hibernate uses its own collection implementations which are enriched with lazy-loading, caching or state change detection semantics. For this reason, persistent collections must be declared as an interface type.
From https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#collections
If your entity is not loaded from the database then you should specify a default implementation that make sense for the use case, but being aware it'll not be the same implementation when the entity is loaded. Generally, this means just using ArrayList in most situations.
I've been dealing with this, now i want to take control of this. Due to data size, I have to control the list which was populated by Hibernate.
#OneToMany(mappedBy="members")
private List<Members> membersList;
So the memberList can grow upto 100, The Sql of android cannot not take it. I meant the huge size of list stored to internal database.
Is there anyway to control the list size before saving to android internal database?
Thanks,
Pusp
you need to set your type of collection.
#OneToMany(mappedBy="members")
private Set<MembersList> memberList;
UPDATE
The documentation says:
Naturally Hibernate also allows to persist collections. These persistent collections can contain almost any other Hibernate type, including: basic types, custom types, components and references to other entities. The distinction between value and reference semantics is in this context very important. An object in a collection might be handled with "value" semantics (its life cycle fully depends on the collection owner), or it might be a reference to another entity with its own life cycle. In the latter case, only the "link" between the two objects is considered to be a state held by the collection.
As a requirement persistent collection-valued fields must be declared as an interface type (see Example 7.2, “Collection mapping using #OneToMany and #JoinColumn”). The actual interface might be java.util.Set, java.util.Collection, java.util.List, java.util.Map, java.util.SortedSet, java.util.SortedMap or anything you like ("anything you like" means you will have to write an implementation of org.hibernate.usertype.UserCollectionType).
Link: https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/collections.html#collections-mapping
In java, if I have a list, I can use addAll(otherList); to add all the elements from one list to another.
What is the equivalent in grails? I have a Domain object with a hasMany relationship. To add to it, I would use something like
Object.addToMyList(someitem);
and it seems like
Object.addAllToMyList(otherList)
does not exist.
What is the equivalent in grails?
To clarify - by default the collection is a Set, but addAll() works with any Collection.
You can call addAll() and it'll work fine, although the back-references won't be set if it's bidirectional. This doesn't affect persistence, just the current in-memory state.
There's nothing built into GORM for this, so I suppose the "right" way is a loop, e.g.
otherItems.each { foo.addToBars(it) }
A question about Java-Hibernate-Validator.
I need to access to a collection attribute when my validation system intercepts an entity insert/update.
I mean, my model defines A class with a set of B elements.
When I call saveOrUpdate(a), the onSave/onFushDirty method of my interceptor is invoked. In that moment I need to know the size of the collection. Is it possible?
Thanks!
Well, according the the docs, your onSave method receives the entity you are persisting. At that point you can cast your entity to what you want. You can either check with instanceof or make overloaded methods that accept your different classes. And from there, access your collection.
Also make sure you have an active session at that point, or that there are no lazy collections.
I have a PurchaseEntity that has a Set inside.
After doing entityManager.persist(purchaseEntity), purchaseEntity itself and purchaseItemEntity's are all saved to DB correctly.
But after that entityManager.persist(purchaseEntity) call, purchaseEntity.getItems() returns null.
Is this a normal behaviour of Hibernate provided entityManager.persist()?
Is there a way to keep the collection remain in the containing entity object after it's persisted?
No, that's not a normal behavior. Furthermore, this is most certainly not Hibernate's doing - it has to be something in your code. Can you post your source?