1

How do get the object I want, without all of the child associations.

I have my class Site:

@Entity
@Table(name = "Sites")
public class Site {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Id_Site", unique = true, nullable = false)
    private long Id_Site;
    private String ...;
    private boolean ...;
    private long ...; 
    private Date ...;
    private Date ...;
    private String ...;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Sequence> sequences = new HashSet<>();

    @ManyToOne
    private ... ...;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<...> ... = new HashSet<>();

    @ManyToOne
    private ... ...;

    public constructor...

    public set..
    public get..
}

I only need a Site object, without the Sequence Associations.

In my Sequence Table, I have:

@Entity
@Table(name = "Sequences")
public class Sequence {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Id_Sequence", unique = true, nullable = false)
    private long Id_Sequence;
    private Date ....;
    private Date ....;
    private String ....;
    private String ....;
    private String ....;
    private int ....;
    private int ....;
    private double ....;
    private double ....;
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<TraceSequence> traceSequences = new HashSet<>();
    @ManyToOne(cascade = CascadeType.ALL)
    private Site site;

    public constructor...

    public set..
    public get..
}

When I use FetchType.Lazy, and call my method:

@Override
public Site findSiteByName(String Name_Site) {
    List<Site> sites = entityManager.createQuery("SELECT s FROM Site s").getResultList();
    for (Site item : sites) {
        if (item.getNom_Site().equals(Name_Site)) {
            return item;
        }
    }
    return null;
}

I get this error:

failed to lazily initialize a collection of role: xxx.xxx.xxx.xxx.xxx.site.Site.sequences, could not initialize proxy - no Session

When I use FetchType.EAGER, I get not only a Site object, but I also get all sequence objects, and all objects of other sequence associations. (I know it is the normal response.)

Could someone who knows why this attempt at lazy initialization doesn't work, please, tell me how to resolve this problem.

Strom
  • 4,146
  • 8
  • 32
Adams
  • 43
  • 1
  • 7
  • You are misunderstanding. Lazy Loading **is** working: that is why you get the error. Some later code is then trying to access the lazy association (a JSON Serializer for example) and it cannot be loaded as there is no session. – Alan Hay Apr 24 '17 at 18:47

6 Answers6

3

These lazy errors happens when the jpa tries to get the data after the session is closed.

But using eager will influence all the queries that include that entity.

Try to use a join fetch in the query instead of the eager.

  • Yes I agree with you. But, the join fetch in the query instead of the eager influence too all queries, just same like using only the Eager. – Adams Apr 25 '17 at 08:43
1

Somewhere in your code you are calling Site.GetSequences(), maybe iterating in the view or in another part of your code. It doesn't look like the piece of code you gave are generating the exception.

I you try to use a collection that is not loaded to your entity, the code throws the exception you mentioned.

To solve this, identify where you are using the sequences and load them before you use by changing the fetch to EAGER or using the JOIN FETCH in your query.

Roque Santos
  • 225
  • 2
  • 8
  • Thank you for helping, I comment all GetSequences that can calling it. But, my question is : if I use Join Fetch I will get all Sequences elements, (same like using eager), and I dont need to get sequences. I juste need the site object without getting all dependences . – Adams Apr 25 '17 at 08:35
0

Returning a hibernate managed entity (or a collection of hibernate managed entities) will most likely cause these sort of problems unless you are super cautious on what is being returned and what was populated by hibernate when session was available.

I would say create a DTO (or a collection of DTO) and populate its fields the way you like. There are many Entity to DTO conversion framework; my fav is ModelMapper.

I also tend to agree with other suggestions to play with FetchType but since DTOs are populated by us we know what we populated as opposed to entity-relationships which are populated by hibernate based on annotations.

If you need something in the DTO you simply ask the entity and since session would be available at that point of time you could populate any field that you think you would need on the UI.

I don't want to hijack this topic towards DTO and Entity but that's how I would do it.

This may be helpful too Avoid Jackson serialization on non fetched lazy objects

Sanjeev Dhiman
  • 1,081
  • 1
  • 9
  • 19
0

Error happen becouse you try execute getSequences(), but becouse of is lazy and session is alredy closed hibernate rais the error. To avoid this error read read sequencese inside query method, "inside" session, like this:

public Site findSiteByName(String Name_Site) {
        List sites = entityManager.createQuery("SELECT s FROM Sites").getResultList();
        for (Site item : sites) {
            if (item.getNom_Site().equals(Name_Site)) {
                item.getSites();
                return item;
            }
        }

        return null;
    }

This is a lazy loading, you read collenction just when you need it!

0

As stated by other SE members above, you are getting this error because session is already closed.

If you want to load a particular object then you can use Hibernate.initialize method. it will execute one additional query to fetch the data of related entity.

Therefore, it is as per need basis and will not be executed all times as compared to Eager loading

0

I'm working on a project that aims to solve common JPA problems when mapping entities to DTOs using ModelMapper. This issue has already been solved on the project. Project link: JPA Model Mapper

On this scenario I believe that we'd want to simply get null for all lazy load entities. For this question specifically, this could be done by using de JPA Model Mapper to map an entity to DTO.

I've already answered the same issue on this question: How to solve the LazyInitializationException when using JPA and Hibernate