Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite mapping with Hibernate Bug #190

Closed
BenDol opened this issue Aug 30, 2014 · 8 comments
Closed

Infinite mapping with Hibernate Bug #190

BenDol opened this issue Aug 30, 2014 · 8 comments

Comments

@BenDol
Copy link

BenDol commented Aug 30, 2014

I have an object that I am mapping called IncidentEntity, which is an Entity object in Hibernate. This object has a number of other Entity relationships for example SectionEntity and ProcessEntity. I have spent a lot of time setting up Dozer so it will deal with the lazy loading on Set's and on Join relationships.

dozer.statistics.enabled=false
org.dozer.util.DozerProxyResolver=org.dozer.util.HibernateProxyResolver
dozer.autoregister.jmx.beans = false
public class LazyLoadSensitiveMapper implements CustomFieldMapper {
    public boolean mapField(Object source, Object destination, Object sourceFieldValue, ClassMap classMap, FieldMap fieldMapping) {
        // If field is initialized, Dozer will continue mapping
        boolean stopMapping = false;

        if(sourceFieldValue instanceof PersistentCollection) {
            stopMapping = !((PersistentCollection) sourceFieldValue).wasInitialized();
        }

        return stopMapping;
    }
}

These two work for the most part. But for some reason its not working on the IncidentEntity after I manually lazy load the ProcessEntity (or SectionEntity) then attempt to map the object. I get an infinite mapping of a ProcessEntity which has a Set of SectionEntity objects and a SectionEntity has a ProcessEntity so it has this infinite recursive map issue (even though in theory it shouldn't happen).

Tested on 5.5.1

IncidentEntity.java

/**
 * Database entity for the 'incidents' table records.<br>
 * Entity domain object is {@link nz.co.doltech.ims.shared.domains.Incident}
 * @author Ben Dol
 * 
 */
@javax.persistence.Entity(name = "incidents")
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class IncidentEntity implements Entity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private int id = Entity.UNSAVED_ID;

    ...

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = ProcessEntity.class)
    @JoinColumn(name="process_state", referencedColumnName="id")
    private ProcessEntity processState;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = SectionEntity.class)
    @JoinColumn(name="section_state", referencedColumnName="id")
    private SectionEntity sectionState;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = ProcessEntity.class)
    @JoinColumn(name="process", referencedColumnName="id")
    private ProcessEntity process;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = SectionEntity.class)
    @JoinColumn(name="section", referencedColumnName="id")
    private SectionEntity section;

    ...

    public SectionEntity getSection() {
        return section;
    }
    public void setSection(SectionEntity section) {
        this.section = section;
    }

    public ProcessEntity getProcess() {
        return process;
    }
    public void setProcess(ProcessEntity process) {
        this.process = process;
    }

    public ProcessEntity getProcessState() {
        return processState;
    }
    public void setProcessState(ProcessEntity processState) {
        this.processState = processState;
    }

    public SectionEntity getSectionState() {
        return sectionState;
    }
    public void setSectionState(SectionEntity sectionState) {
        this.sectionState = sectionState;
    }
    ...
}

ProcessEntity.java

/**
 * Database entity for the 'processes' table records.<br>
 * Entity domain object is {@link nz.co.doltech.ims.shared.domains.Process}
 * @author Ben Dol
 * 
 */
@javax.persistence.Entity(name = "processes")
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class ProcessEntity implements Entity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id = Entity.UNSAVED_ID;

    ...

    @OneToMany(fetch=FetchType.LAZY, mappedBy="process")
    //@Cascade({CascadeType.SAVE_UPDATE})
    private Set<SectionEntity> sections = new HashSet<SectionEntity>();

    @Override
    public int getId() {
        return this.id;
    }
    public void setId(int id) {
        this.id = id;
    }

    ...

    public Set<SectionEntity> getSections() {
        return sections;
    }
    public void setSections(Set<SectionEntity> sections) {
        this.sections = sections;
    }

    ...
}

SectionEntity.java

/**
 * Database entity for the 'sections' table records.<br>
 * Entity domain object is {@link nz.co.doltech.ims.shared.domains.Section}
 * @author Ben Dol
 * 
 */
@javax.persistence.Entity(name = "sections")
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class SectionEntity implements Entity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id = Entity.UNSAVED_ID;

    ...

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = ProcessEntity.class)
    @JoinColumn(name="process", referencedColumnName="id")
    private ProcessEntity process;

    @Override
    public int getId() {
        return this.id;
    }
    public void setId(int id) {
        this.id = id;
    }

    ...

    public ProcessEntity getProcess() {
        return process;
    }
    public void setProcess(ProcessEntity process) {
        this.process = process;
    }

    ...
}

Am I missing something? I have debugged the IncidentEntity object that I am mapping to make sure it hasn't recursively loaded before it is even sent off to be mapped and it hasn't.

Log output:

08:20:09,636 ERROR [org.dozer.MappingProcessor] - Field mapping error -->
  MapId: null
  Type: null
  Source parent class: nz.co.doltech.ims.server.entities.SectionEntity
  Source field name: process
  Source field type: class nz.co.doltech.ims.server.entities.ProcessEntity_$$_javassist_28
  Source field value: nz.co.doltech.ims.server.entities.ProcessEntity@792ee0e0
  Dest parent class: nz.co.doltech.ims.shared.domains.Section
  Dest field name: process
  Dest field type: nz.co.doltech.ims.shared.domains.Process
08:20:09,690 ERROR [org.dozer.MappingProcessor] - Field mapping error -->
  MapId: null
  Type: null
  Source parent class: nz.co.doltech.ims.server.entities.ProcessEntity
  Source field name: sections
  Source field type: class org.hibernate.collection.PersistentSet
  Source field value: [nz.co.doltech.ims.server.entities.SectionEntity@3209ee2d, nz.co.doltech.ims.server.entities.SectionEntity@29f3e605, nz.co.doltech.ims.server.entities.SectionEntity@de0cb4c, nz.co.doltech.ims.server.entities.SectionEntity@2142f1b2]
  Dest parent class: nz.co.doltech.ims.shared.domains.Process
  Dest field name: sections
  Dest field type: java.util.Set
08:20:09,734 ERROR [org.dozer.MappingProcessor] - Field mapping error -->
  MapId: null
  Type: null
  Source parent class: nz.co.doltech.ims.server.entities.SectionEntity
  Source field name: process
  Source field type: class nz.co.doltech.ims.server.entities.ProcessEntity_$$_javassist_28
  Source field value: nz.co.doltech.ims.server.entities.ProcessEntity@792ee0e0
  Dest parent class: nz.co.doltech.ims.shared.domains.Section
  Dest field name: process
  Dest field type: nz.co.doltech.ims.shared.domains.Process
08:20:09,785 ERROR [org.dozer.MappingProcessor] - Field mapping error -->
  MapId: null
  Type: null
  Source parent class: nz.co.doltech.ims.server.entities.ProcessEntity
  Source field name: sections
  Source field type: class org.hibernate.collection.PersistentSet
  Source field value: [nz.co.doltech.ims.server.entities.SectionEntity@3209ee2d, nz.co.doltech.ims.server.entities.SectionEntity@29f3e605, nz.co.doltech.ims.server.entities.SectionEntity@de0cb4c, nz.co.doltech.ims.server.entities.SectionEntity@2142f1b2]
  Dest parent class: nz.co.doltech.ims.shared.domains.Process
  Dest field name: sections
  Dest field type: java.util.Set
08:20:09,839 ERROR [org.dozer.MappingProcessor] - Field mapping error -->
  MapId: null
  Type: null
  Source parent class: nz.co.doltech.ims.server.entities.SectionEntity
  Source field name: process
  Source field type: class nz.co.doltech.ims.server.entities.ProcessEntity_$$_javassist_28
  Source field value: nz.co.doltech.ims.server.entities.ProcessEntity@792ee0e0
  Dest parent class: nz.co.doltech.ims.shared.domains.Section
  Dest field name: process
  Dest field type: nz.co.doltech.ims.shared.domains.Process
08:20:09,898 ERROR [org.dozer.MappingProcessor] - Field mapping error -->
  MapId: null
  Type: null
  Source parent class: nz.co.doltech.ims.server.entities.ProcessEntity
  Source field name: sections
  Source field type: class org.hibernate.collection.PersistentSet
  Source field value: [nz.co.doltech.ims.server.entities.SectionEntity@3209ee2d, nz.co.doltech.ims.server.entities.SectionEntity@29f3e605, nz.co.doltech.ims.server.entities.SectionEntity@de0cb4c, nz.co.doltech.ims.server.entities.SectionEntity@2142f1b2]
  Dest parent class: nz.co.doltech.ims.shared.domains.Process
  Dest field name: sections
  Dest field type: java.util.Set
at org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:361)
    at org.dozer.MappingProcessor.mapField(MappingProcessor.java:307)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:267)
    at org.dozer.MappingProcessor.mapToDestObject(MappingProcessor.java:216)
    at org.dozer.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:196)
    at org.dozer.MappingProcessor.mapCustomObject(MappingProcessor.java:512)
    at org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:465)
    at org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:361)
    at org.dozer.MappingProcessor.mapField(MappingProcessor.java:307)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:267)
    at org.dozer.MappingProcessor.mapToDestObject(MappingProcessor.java:216)
    at org.dozer.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:196)
    at org.dozer.MappingProcessor.mapCustomObject(MappingProcessor.java:512)
    at org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:465)
    at org.dozer.MappingProcessor.addToSet(MappingProcessor.java:757)
    at org.dozer.MappingProcessor.mapCollection(MappingProcessor.java:570)
    at org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:453)
    at org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:361)
    at org.dozer.MappingProcessor.mapField(MappingProcessor.java:307)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:267)
    at org.dozer.MappingProcessor.mapToDestObject(MappingProcessor.java:216)
    at org.dozer.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:196)
    at org.dozer.MappingProcessor.mapCustomObject(MappingProcessor.java:512)
    at org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:465)
    at org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:361)
    at org.dozer.MappingProcessor.mapField(MappingProcessor.java:307)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:267)
       .....

I have no idea how to reproduce this issue but I'm farely sure it is a bug somewhere.

@garethahealy
Copy link
Collaborator

@BenDol ; is this still an issue?

@garethahealy
Copy link
Collaborator

Closing due to inactivity.

@heloufir
Copy link

Do you have a solution, I almost tried all the solution in the stackoverflow, ... and other forums, but none of them worked for me. I have the same issue

@garethahealy
Copy link
Collaborator

@eloufirhatim ; see the below. Someone else has hit a similar:

@heloufir
Copy link

heloufir commented Oct 1, 2018

@garethahealy thanks for your reply.
I was using the Dozer

Before

<dependency>
    <groupId>net.sf.dozer</groupId>
    <artifactId>dozer</artifactId>
    <version>${dozer.version}</version>
</dependency>
<dependency>
    <groupId>net.sf.dozer</groupId>
    <artifactId>dozer-spring</artifactId>
    <version>${dozer.version}</version>
</dependency>

After, I switched for the DozerMapper/dozer plugin (this repository)

<dependency>
    <groupId>com.github.dozermapper</groupId>
    <artifactId>dozer-core</artifactId>
    <version>${dozer.version}</version>
</dependency>
<dependency>
    <groupId>com.github.dozermapper</groupId>
    <artifactId>dozer-spring4</artifactId>
    <version>${dozer.version}</version>
</dependency>

I thought I was using this from the begining 😄

But, can you explain to me the difference between these two libraries please? They are identical ? because, their configuration are pretty the same.

Thanks in advance.

@garethahealy
Copy link
Collaborator

Its the same project, but because of migrating to github and no longer controlling the sf site, the GAV changed.

@heloufir
Copy link

heloufir commented Oct 1, 2018

Ok, thank you for the information.
Now all is working perfectly 😃

@heloufir
Copy link

heloufir commented Oct 4, 2018

Hello,
The same issue is back again, when debugging I see that my object is not mapped like I configured in the XML mapping file, but what is weird, is when I restart the server... It works juste fine.

I cereated an issue for it: https://github.com/DozerMapper/dozer/issues/704

Can you please help.
Thanks in advance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants