0

I've got two classes Participant and TimeWindow. Multiple participants can register for multiple TimeWindow, hence the ManyToMany relation

@Entity
@Table
public class Participant {
    @Id
    @SequenceGenerator(
            name = "participant_sequence",
            sequenceName = "particant_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "participant_sequence"
    )
    private Long id;
    private String name;
    private String number;
    private String details;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "ParticipantCreneaux")
    private Collection<TimeWindow> registeredTimeWindow;


    public Participant() {

    }
    public Participant(String nom, String num, String details) {
        this.name = nom;
        this.number = num;
        this.details = details;
        this.registeredTimeWindow = new ArrayList<>();
    }
    public void addTimeWindow(TimeWindow c){
        registeredTimeWindow.add(c);
    }
    public void removeTimeWindow(TimeWindow c){
        registeredTimeWindow.remove(c);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    public Collection<TimeWindow> getRegisteredTimeWindow() {
        return registeredTimeWindow;
    }
}

And the TimeWindow class:

@Entity
@Table
public class TimeWindow {
    @Id
    @SequenceGenerator(
            name = "creneau_sequence",
            sequenceName = "creneau_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "creneau_sequence"
    )
    private Long id;
    private LocalTime hourStart;
    private LocalTime hourEnd;

    public Collection<Participant> getListParticipants() {
        return listParticipants;
    }

    @ManyToMany(fetch = FetchType.LAZY,cascade=CascadeType.ALL,mappedBy = "registeredTimeWindow")
    private Collection<Participant> listParticipants;

    public TimeWindow(LocalTime hourStart, LocalTime hourEnd) {
        this.hourStart = hourStart;
        this.hourEnd = hourEnd;
        this.listParticipants = new ArrayList<>();
    }

    public TimeWindow() { }

    public LocalTime getHourEnd() {
        return hourEnd;
    }

    public void setHourStart(LocalTime hourStart) {
        this.hourStart = hourStart;
    }

    public void setHourEnd(LocalTime hourEnd) {
        this.hourEnd = hourEnd;
    }

    public LocalTime getHourStart() {
        return hourStart;
    }

    public int getNbParticipants(){
        return listParticipants.size();
    }
    public void addParticipant(Participant participant){
        this.listParticipants.add(participant);
    }
    public void removeParticipant(Participant participant){
        this.listParticipants.remove(participant);
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }
}

Right now I'm still learning Spring boot, I haven't found anything about it so far or anything that helped me.

The error is when I summon my participant's TimeWindow Collection that i've gotten through the DataBase in the Config class. In the debugger my Participant looks like this

id:123
name:"hisName"
number:"321"
details:"some details"
registeredTimeWindow:{PersistentBag@10927}Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception.

At first i thought it was normal because of the Lazy option, i had to invoke the array through the getter, however it is wrong and the getter give me the exact same object.

FetchType.EAGER works fine, however I can't afford to do it. I've tried to get some help from someone a bit more experienced than I am, but without success. It should be possible to work around that issue within the JPA Repositories, but it feels like such a waste not to be able to use the getter.

  • I assume your `spring.jpa.open-in-view` configuration property is set to false? I also wonder if the relation is loaded successfully in the response, or if it also fails? – Serg Vasylchak Apr 21 '21 at 14:27
  • Does this answer your question? [How to fix org.hibernate.LazyInitializationException - could not initialize proxy - no Session](https://stackoverflow.com/questions/21574236/how-to-fix-org-hibernate-lazyinitializationexception-could-not-initialize-prox) – crizzis Apr 21 '21 at 15:28

1 Answers1

0

You are trying to use lazy data after closing a transaction, and yes, one of the ways is usage EAGER. Another way - usage @Transactional on a method that using this data.