users@glassfish.java.net

Problem with JPA and entity relationships not being seen

From: <glassfish_at_javadesktop.org>
Date: Sun, 13 Jan 2008 09:01:04 PST

All of the following is within a stateless EJB session beans.

I have an entity relationship that looks like this: DeviceEntity has a @OneToMany relationship within contained DeviceEntities. The relationship is recursive in that each of those contained DeviceEntity's can contain other DeviceEntity's. The relationship is bidirectional. Here are the relationships:

    /**
     * Holds the list of direct children of the DeviceEntity
     */
    @OneToMany(mappedBy="parentEntity", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch=FetchType.EAGER)
    @OrderBy("relativePosition ASC")
    private List<DeviceEntity> containedEntities = new ArrayList<DeviceEntity>();
    
    /**
     * Holds the parent entity of the DeviceEntity
     */
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private DeviceEntity parentEntity;
    
I create a relationship that consists of a Chassis DeviceEntity, which contains a InterfaceModuleContainer, which contains an UserTHGInterfaceModule. I wire up the bidirectional relationship correctly and persist the Chassis. I have the persistence logging set to FINEST. I see all of the inserts into the database being performed correctly and I even put a method in to dump the relationships from my Chassis device entity on down. All i okay.

In the another immediate EJB invocation, I am retrieving the Chassis and trying to access the contained elements. I am actually testing that I can remove this Chassis at this point.

The Chassis and its contained InterfaceModuleContainer are present, but the InterfaceModuleContainer which is supposed to contain an InterfaceModule is missing the InterfaceModule.

Here is a small output of the transactions. The first "chassis contents" output is right after the persist of the chassis, and the rest is trying to retrieve the Chassis along with its related entities. The second "chassis contents" shows that the "UserTHGInterfaceModule" entity is missing from the InterfaceModuleContainer.

My dump routine looks like:

    void dumpDeviceContents(DeviceEntity deviceEntity, String indent) {
        System.out.println(indent + deviceEntity + ", parent: " + deviceEntity.getParentEntity());
        for (DeviceEntity containedEntity : deviceEntity.getContainedEntities()) {
            dumpDeviceContents(containedEntity, indent + " ");
        }
    }

So as you can see, I am traversing and validating both directions of the relationship.

What is really strange is that if I put a "em.refresh(chassis)" call the second EJB invocation, then the relationship shows up correctly. Also, if I don't put the refresh call in, but rather restart the application server, again the relationship shows up correctly. A final strange this is that while creating the initial relationship, I have a query being preformed to validate that there will be no duplicate entities. The query looks like:

            SnmpDevice snmpDevice = newChassis.getSnmpDevice();
            snmpDevice.setIpFromIpAddress(cmd.getIpAddress());
            // Now see if there is another SNMP device with this IP address
            Query query = em.createNamedQuery("SnmpDevice.findByIp");
            query.setParameter("ip", cmd.getIpAddress().getValue());
            SnmpDevice otherSnmpDevice = null;
            try {
                otherSnmpDevice = (SnmpDevice) query.getSingleResult();
            } catch (NoResultException noResultException) {
                // There might be no device with this IP address
            }
            if (null != otherSnmpDevice && !snmpDevice.equals(otherSnmpDevice)) {
                throw new DuplicateIPAddressException("A device has already been assigned the IP address:" + cmd.getIpAddress().toString());
            }

If I comment out this query, the relationship in the second EJB invocation also works even without a refresh.

None of this makes sense. I'm at a loss as to why in the second EJB invocation, I am not seeing this one relationship. I'm thinking it is a bug in the JPA provider.

Any ideas?
[Message sent by forum member 'bbergquist' (bbergquist)]

http://forums.java.net/jive/thread.jspa?messageID=253609