3

Could anyone help me how to deal with @Any relationship?

I have an interface InteractionParticipate which is implemented by everyone who wants to take a part in some kind of messaging interaction. A message is represented by InteractionMessage which has a transmitter and a receiver. Since we don't know which entity implementing InteractionParticipate will be the receiver (or transmitter) of the message we have to use @Any relationship.

I have read this one which inspired me and wrote in InteractionMessage something like that:

@Any(metaColumn = @Column(name = "Transmitter_Type"))
@AnyMetaDef(
        idType = "long",
        metaType = "string",
        metaValues = {
                @MetaValue(value = "Applicant", targetEntity = Applicant.class),
                @MetaValue(value = "Vacancy", targetEntity = Vacancy.class)
        })
@JoinColumn(name = "Transmitter_Id")
@LazyToOne(LazyToOneOption.FALSE)
private InteractionParticipate transmitter;

@Any(metaColumn = @Column(name = "Receiver_Type"))
@AnyMetaDef(idType = "long", metaType = "string",
        metaValues = {
                @MetaValue(targetEntity = Applicant.class, value = "Applicant"),
                @MetaValue(targetEntity = Vacancy.class, value = "Vacancy")
        })
@JoinColumn(name = "Receiver_Id")
@LazyToOne(LazyToOneOption.FALSE)
private InteractionParticipate receiver;

Database is created well and I can see entities save correctly. But when I try to get an InteractionMessage from database

InteractionMessage message = (InteractionMessage) session.get(InteractionMessage.class, id);

I face I cannot get neither receiver nor transmitter because Method threw 'org.hibernate.LazyInitializationException' exception. Cannot evaluate ... Vacancy_$$_javassist_49.toString(). (Vacancy class is implementing InteractionParticipate.)

I tried to play with @LazyToOne and even @LazyCollection but failed.

Please help me to figure it out. Thanks in advance!

Community
  • 1
  • 1

1 Answers1

1

You are trying to access a collection of a detached object. A detached object means it is not connected to a session. As a result, when accessing a lazy collection, you receive an exception. This can happen for different reasons. For example, you receive the object by serialization from the front-end. There are 2 possible solutions, depending what result is desired.

1) You can define the collection to be eagerly fetched. This means that the collection is initialized as soon as the parent object is initialized. 2) You can merge the object (T mergedObject em.merge(detachedObject);) an access its collection.

A small warning: em.merge() returns a merged object. However, the old one is still detached, so remember to access the merged one.

Dima K
  • 91
  • 4