Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Retrieve partial objects from @ManyToMany relation
PostPosted: Sat Sep 23, 2017 3:32 pm 
Newbie

Joined: Wed Sep 13, 2017 10:21 am
Posts: 7
Hi,

Recently I was able to find help here, so I will ask for such again. I am helping in resolving some problem and every opinion is important. We are having two tables Application and BusinessUnit represented by ApplicationBean and BusinessUnitBean. They have many to many relation. Every application can have many units assigned to it. Every application have some basic properties and a set of units that represents the manyToMany relation. The BusinessUnit on the other hand has also some basic properties and ManyToOne relation to itself because every unit can have a parent unit. The problem is that we are testing the creation of 1500 applications and every application can have from 60 to 120 units. When we try to select all applications, the result is retrieved too slow. The result from the big join query in hibernate is fast, but the initialization of the collection as objects is slow. So we have decided to fetch only the necessary properties per case, it is very fast when we do not need the set with units, but now we need them or at least their ids. With projection we can get the applications with only some properties initialized. But is it possible to get the list with all units per application, but only with id initialized for every unit. These are the beans:
Code:
public class ApplicationBean implements Application, Cloneable {

    /** Unique application name. */
    @Column(name="name", nullable = false)
    @AuditedProperty(name = "Name")
    private String mName = null;
   
    /** Application type. */
    @Column(name="type", nullable = false, updatable = false)
    @AuditedProperty(name = "Type")
    private String mApplicationType = null;
   
    /** Notes for this application. */
    @Column (name="notes", length=2048)
    @AuditedProperty(name = "Notes")
    private String mNotes = null;

@ManyToMany(fetch=FetchType.EAGER, targetEntity=BusinessUnitBean.class)
    @JoinTable(name="Application_BusinessUnit", joinColumns = @JoinColumn(name="applicationId", nullable=false),
            inverseJoinColumns=@JoinColumn(name="businessUnitId", nullable=false),
            foreignKey = @ForeignKey(name="FKApplication_BusinessUnit"),
            inverseForeignKey = @ForeignKey(name="FKBusinessUnit_Application")
            )
    @org.hibernate.annotations.Cascade( { org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.REPLICATE, org.hibernate.annotations.CascadeType.MERGE })
    @Fetch(FetchMode.SELECT)
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region="ApplicationCache")
    @AuditedProperty(name = "Business units", nameOnly = true)
    private Set<BusinessUnit> mBusinessUnits = new HashSet<BusinessUnit>();

    /**
     * The unique identifer for this object. Created and managed by the persistence implementation.
     */
    @XmlAttribute (name="id", required=false)
    @javax.persistence.Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "some.class.Uuid")
    @Column(name = "id", length=32)
    private String mUniqueId = null;

//some other properties

}


public class BusinessUnitBean implements BusinessUnit, Cloneable {
    /** Unique name. */
    @Column(name="name", nullable=false)
    @AuditedProperty(name = "Name")
    private String mName = null;

    /** Unique id object of the parent business unit. */
    @ManyToOne(fetch=FetchType.EAGER, targetEntity=BusinessUnitBean.class)
    @JoinColumn(name="parentId", foreignKey = @ForeignKey(name="FKBusinessUnit_Parent"))
    @AuditedProperty(name = "Parent business unit", nameOnly = true)
    private BusinessUnit mParent = null;

    /**
     * The unique identifier for this object. Created and managed by the persistence implementation.
     */
    @XmlAttribute (name="id", required=false)
    @javax.persistence.Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "some.class.Uuid")
    @Column(name = "id", length=32)
    private String mUniqueId = null;

//some other properties
}



I will be very grateful to anyone that has some idea. For now we have tried to do a inner join without Hibernate between the Application and Application_BusinessUnit table in order to get all the ids of units per specific application. But it is still pretty slow. I have tried something but it works only when stripping the simple properties. When I want only Application with id, name and type, I use a named query like "@NamedQuery(name = "findAllApplicationNames", query = "select new ApplicationBean(mUniqueId, mName, mApplicationType) from ApplicationBean order by mName asc")". But when I have tried to add the set with units in the constructor, there were some problems, I can not use a set in the named query. The same was tried with projection also.

Thank you.


Top
 Profile  
 
 Post subject: Re: Retrieve objects from ManyToMany relation partially
PostPosted: Sun Sep 24, 2017 2:09 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1582
Location: Romania
Quote:
When we try to select all applications, the result is retrieved too slow.


As I explained in my book, you NEVER need to select all data at once. What would be the use case?

1. Are you going to display all 1000 Applications in the UI? They will not fit.
2. Are you trying to process all that data. Then just use smaller batches.

Also, you don't need to always use collections, especially if the number of child entries is large.

A JPQL query is always going to be more flexible than a managed collection.

Therefore, just use queries and restrict the amount of data that you fetch at a time. Also, collections will not work with both JOIN FETCH and pagination, unless you use native SQL queries.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: Retrieve partial objects from @ManyToMany relation
PostPosted: Wed Sep 27, 2017 6:59 am 
Newbie

Joined: Wed Sep 13, 2017 10:21 am
Posts: 7
Thank you. I think it is time to read more about hibernate, but not when I only need to fix something.


Top
 Profile  
 
 Post subject: Re: Retrieve partial objects from @ManyToMany relation
PostPosted: Wed Sep 27, 2017 10:22 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1582
Location: Romania
When does the cycle of tasks ever ends while working on a project? You fix one thing only to start addressing the next issue. It's called software development after all.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.