/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.ilb.common.jpa.tools;

import java.util.List;
import javax.persistence.EntityManager;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.OneToManyMapping;
import org.eclipse.persistence.mappings.OneToOneMapping;
import org.eclipse.persistence.sessions.Session;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

/**
 *
 * @author slavb
 */
public class DescriptorUtils {

    EntityManager entityManager;

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public void fixInverseLinks(Object entity) {
        final BeanWrapper src = new BeanWrapperImpl(entity);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        ClassDescriptor cd = entityManager.unwrap(Session.class).getDescriptor(entity);
        if (cd == null) {
            return;
        }
        for (java.beans.PropertyDescriptor pd : pds) {
            DatabaseMapping dm = cd.getMappingForAttributeName(pd.getName());
            if (dm != null) {
                if (dm instanceof OneToManyMapping) {
                    OneToManyMapping dmOtM = (OneToManyMapping) dm;
                    if (dmOtM.getMappedBy() != null) {
                        List srcValue = (List) src.getPropertyValue(pd.getName());
                        if (srcValue != null) {
                            for (Object v : srcValue) {
                                final BeanWrapper srcv = new BeanWrapperImpl(v);
                                srcv.setPropertyValue(dmOtM.getMappedBy(), entity);
                                fixInverseLinks(v);
                            }
                        }

                    }
                }
                if (dm instanceof OneToOneMapping) {
                    OneToOneMapping dmOtO = (OneToOneMapping) dm;
                    if (dmOtO.getMappedBy() != null) {
                        Object srcValue = src.getPropertyValue(pd.getName());
                        if (srcValue != null) {
                            final BeanWrapper srcv = new BeanWrapperImpl(srcValue);
                            srcv.setPropertyValue(dmOtO.getMappedBy(), entity);
                            fixInverseLinks(srcValue);
                        }

                    }
                }
            }

        }
    }

}

@@ -651,16 +651,64 @@
 perImpl;
+%0Aimport ru.ilb.common.jpa.jaxb.EclipseLinkUtils;
 %0A%0A/**%0A *
@@ -905,25 +905,184 @@
 ager;%0A    %7D%0A
+    /**%0A     * Method fixes all one-to-many and one-to-one fields with mapped-by property%0A     * by filling owning side reference%0A     * @param entity %0A     */
 %0A
-
     public v
@@ -1858,32 +1858,76 @@
 srcValue != null
+ && EclipseLinkUtils.isInitialized(srcValue)
 ) %7B%0A            
@@ -2528,32 +2528,32 @@
 (pd.getName());%0A
-
                 
@@ -2572,32 +2572,76 @@
 srcValue != null
+ && EclipseLinkUtils.isInitialized(srcValue)
 ) %7B%0A            

exclude lazy loaded fields