-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Dom4j EntityMode with One-To-Many and Many-To-Ones
PostPosted: Thu May 06, 2010 4:21 pm 
Newbie

Joined: Thu May 22, 2008 9:48 am
Posts: 13
I'm attempting to sort out some bumps in the road I've encountered with this entity mode. I'd like to use it as typically described, as a transport between databases using replicate.

Please note these mappings are dynamic map entity mode.

The only way this stuff works is if I have embed-xml=false on the Collection in the Root entity and embed-xml=true on the inverse many-to-one in Typical entity. However, I would like to have NO embed-xml since I may only transport certain subsets of data. If I change the Typical embed-xml to false, I get the following:
Code:
java.lang.String cannot be cast to org.dom4j.Element
java.lang.ClassCastException: java.lang.String cannot be cast to org.dom4j.Element
        at org.hibernate.property.Dom4jAccessor$AttributeGetter.get(Dom4jAccessor.java:194)
        at org.hibernate.tuple.entity.AbstractEntityTuplizer.getVersion(AbstractEntityTuplizer.java:264)
        at org.hibernate.persister.entity.AbstractEntityPersister.getVersion(AbstractEntityPersister.java:3629)
        at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3347)
        at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:204)
        at org.hibernate.engine.ForeignKeys$Nullifier.isNullifiable(ForeignKeys.java:160)
        at org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:92)
        at org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:70)
        at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:311)
        at org.hibernate.event.def.DefaultReplicateEventListener.onReplicate(DefaultReplicateEventListener.java:145)
        at org.hibernate.impl.SessionImpl.fireReplicate(SessionImpl.java:959)
        at org.hibernate.impl.SessionImpl.replicate(SessionImpl.java:946)
        at com.ciminc.compass.synchronizer.Dom4jSerializationTest.dom4jReplicateSimpleGraph(Dom4jSerializationTest.java:182)



The XML output as a result of the BAD embed-xml=false on Typical with all embed-xml=false on Root:
Code:

                 <Root guid="4028B881286F240C01286F24248C0009" version="0">
                  <uniqueOne>one</uniqueOne>
                  <uniqueTwo>two</uniqueTwo>
                 </Root>
                 <Typical guid="4028B881286F240C01286F24248E000A" version="0">
                  <root>4028B881286F240C01286F24248C0009</root>
                  <uniqueOne>one</uniqueOne>
                 </Typical>



The working code with embed-xml=true:

Mappings
Code:
<hibernate-mapping>
  <class entity-name="Root" table="ROOT" node="Root">
    <id name="guid" type="com.ciminc.hibernate.type.GuidType" node="@guid">
      <column name="GUID"/>
      <generator class="org.hibernate.id.UUIDHexGenerator"/>
    </id>
    <natural-id mutable="true">
      <property name="uniqueOne" type="string" unique="true">
        <column name="UNIQUE_ONE"/>
      </property>
      <property name="uniqueTwo" type="string" unique="true">
        <column name="UNIQUE_TWO"/>
      </property>
    </natural-id>
    <version name="version" type="java.lang.Long" node="@version">
      <column name="VERSION"/>
    </version>
    <bag name="typicals" inverse="true" table="TYPICAL" fetch="select" cascade="save-update,replicate,evict" embed-xml="false">
      <key on-delete="noaction">
        <column name="ROOT_GUID" not-null="true"/>
      </key>
      <one-to-many entity-name="Typical" embed-xml="false" node="Typical"/>
    </bag>
  </class>

  <class entity-name="Typical" table="TYPICAL" node="Typical">
    <id name="guid" type="com.ciminc.hibernate.type.GuidType" node="@guid">
      <column name="GUID"/>
      <generator class="org.hibernate.id.UUIDHexGenerator"/>
    </id>
    <natural-id mutable="true">
      <many-to-one name="root" entity-name="Root" unique="true" embed-xml="true" node="root">
        <column name="ROOT_GUID" not-null="true"/>
      </many-to-one>
      <property name="uniqueOne" type="string" unique="true">
        <column name="UNIQUE_ONE"/>
      </property>
    </natural-id>
    <version name="version" type="java.lang.Long" node="@version">
      <column name="VERSION"/>
    </version>
    <property name="displaystring" type="string">
      <column name="DISPLAYSTRING"/>
    </property>
  </class>
</hibernate-mapping>


Test
Code:
    @Test
    public void dom4jReplicateSimpleGraph() throws IOException, DocumentException {
        log.info("Beginning dom4j");
        List<Element> elements = null;
        Map<String,Object> rootObj = null;
        Map<String,Object> typicalObj = null;

        Session dom4jSession = sessionLocal.getSession(EntityMode.DOM4J);
        assertEquals(0, dom4jSession.createQuery("from Root").list().size());

        // Create a local graph
        rootObj = new HashMap<String,Object>();
        rootObj.put("uniqueOne", "one");
        rootObj.put("uniqueTwo", "two");
        rootObj.put("typicals", new ArrayList());
        typicalObj = new HashMap<String,Object>();
        typicalObj.put("uniqueOne", "one");
        typicalObj.put("root", rootObj);
        ((List)rootObj.get("typicals")).add(typicalObj);
        sessionLocal.save("Root", rootObj);
        sessionLocal.flush();
        assertEquals(1, sessionLocal.createQuery("from Root").list().size());
        assertEquals(1, sessionLocal.createQuery("from Typical").list().size());
        sessionLocal.clear();

        Document dom4jDoc = new DefaultDocument();
        Element syncElement = new DefaultElement("synchronization-set");
        dom4jDoc.add(syncElement);

        // Add Roots...no embedded-xml
        elements = dom4jSession.createQuery("from Root").list();
        assertEquals(1, elements.size());
        for (Element rootElement: elements) {
            syncElement.add(rootElement);
        }
        dom4jSession.clear();

        // Add Typicals since Root references
        elements = dom4jSession.createQuery("from Typical").list();
        assertEquals(1, elements.size());
        for (Element rootElement: elements) {
            syncElement.add(rootElement);
        }
        dom4jSession.clear();

        XMLWriter writer = new XMLWriter(new FileWriter("target/serialize-entities.xml"));//, OutputFormat.createPrettyPrint());
        writer.write(dom4jDoc);
        writer.close();

        sessionLocal.getTransaction().rollback();
        sessionLocal.beginTransaction();
        assertEquals(0, sessionLocal.createQuery("from Root").list().size());
        sessionLocal.clear();

        SAXReader reader = new SAXReader();
        dom4jDoc = reader.read("target/serialize-entities.xml");
        //syncElement = dom4jDoc.getRootElement();

        for (Object elObj: dom4jDoc.getRootElement().elements()) {
            if (elObj instanceof DefaultElement) {
                Element rootElement = (Element) elObj;
                dom4jSession.replicate(rootElement, ReplicationMode.OVERWRITE);
            }
        }
        dom4jSession.flush();

        assertEquals(1, sessionLocal.createQuery("from Root").list().size());
        assertEquals(1, sessionLocal.createQuery("from Typical").list().size());
    }


I edit the mappings a little on pasting because they were a bit more verbose, if there's issues, let me know and I'll fix them.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.