Refined dynamic model/XML doco
git-svn-id: https://svn.jboss.org/repos/hibernate/trunk/Hibernate3/doc@6083 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
bf75f1c24c
commit
4f2d1c22fc
|
@ -372,9 +372,10 @@
|
|||
<para>
|
||||
<literal>entity-name</literal> (optional): Hibernate3 allows a class to be mapped
|
||||
multiple times (to different tables, potentially), and allows entity mappings that
|
||||
are represented by Maps or XML at the java level. In these cases, you should
|
||||
are represented by Maps or XML at the Java level. In these cases, you should
|
||||
provide an explicit arbitrary name for the entity. See
|
||||
<xref linkend="persistent-classes-dynamic"/> for more information.
|
||||
<xref linkend="persistent-classes-dynamicmodels"/> and <xref linkend="xml"/>
|
||||
for more information.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="class18">
|
||||
|
|
|
@ -377,7 +377,7 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
|
|||
the other techniques described above.
|
||||
</para>
|
||||
|
||||
<table frame="topbot" id="configuration-optional-properties" revision="7">
|
||||
<table frame="topbot" id="configuration-optional-properties" revision="8">
|
||||
<title>Hibernate Configuration Properties</title>
|
||||
<tgroup cols="2">
|
||||
<colspec colname="c1" colwidth="1*"/>
|
||||
|
@ -482,6 +482,19 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
|
|||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>hibernate.default_entity_mode</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Set a default mode for entity representation for all sessions
|
||||
opened from this <literal>SessionFactory</literal>
|
||||
<para>
|
||||
<literal>dynamic-map</literal>, <literal>dom4j</literal>,
|
||||
<literal>pojo</literal>
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>hibernate.order_updates</literal>
|
||||
|
|
|
@ -309,18 +309,38 @@ public class DomesticCat extends Cat {
|
|||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="persistent-classes-dynamic" revision="2">
|
||||
<title>Dynamic models</title>
|
||||
<sect1 id="persistent-classes-dynamicmodels">
|
||||
<title>Dynamic modelss</title>
|
||||
|
||||
<para>
|
||||
Hibernate also supports dynamic domain models, using <literal>Map</literal>s of
|
||||
<literal>Map</literal>s. With this approach, you don't write persistent classes,
|
||||
a Hibernate mapping file for each "entity" is sufficient:
|
||||
<emphasis>Note that the following features are currently considered
|
||||
experimental and may change in the near future.</emphasis>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Persistent entities don't necessarily have to be represented as POJO classes
|
||||
or as JavaBean objects at runtime. Hibernate also supports dynamic models
|
||||
(using <literal>Map</literal>s of <literal>Map</literal>s at runtime) and the
|
||||
representation of entities as DOM4J trees. With this approach, you don't
|
||||
write persistent classes, only mapping files.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
By default, Hibernate works in normal POJO mode. You may set a default entity
|
||||
representation mode for a particular <literal>SessionFactory</literal> using the
|
||||
<literal>default_entity_mode</literal> configuration option (see
|
||||
<xref linkend="configuration-optional-properties"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following examples demonstrates the representation using <literal>Map</literal>s.
|
||||
First, in the mapping file, an <literal>entity-name</literal> has to be declared
|
||||
instead of (or in addition to) a class name:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[<hibernate-mapping>
|
||||
|
||||
<class entity-name="TestMap">
|
||||
<class entity-name="Customer">
|
||||
|
||||
<id name="id"
|
||||
type="long"
|
||||
|
@ -336,16 +356,16 @@ public class DomesticCat extends Cat {
|
|||
column="ADDRESS"
|
||||
type="string"/>
|
||||
|
||||
<many-to-one name="parent"
|
||||
column="PARENT_ID"
|
||||
class="TestMap"/>
|
||||
<many-to-one name="organization"
|
||||
column="ORGANIZATION_ID"
|
||||
class="Organization"/>
|
||||
|
||||
<bag name="children"
|
||||
<bag name="orders"
|
||||
inverse="true"
|
||||
lazy="false"
|
||||
cascade="all">
|
||||
<key column="PARENT_ID"/>
|
||||
<one-to-many class="TestMap"/>
|
||||
<key column="CUSTOMER_ID"/>
|
||||
<one-to-many class="Order"/>
|
||||
</bag>
|
||||
|
||||
</class>
|
||||
|
@ -353,23 +373,38 @@ public class DomesticCat extends Cat {
|
|||
</hibernate-mapping>]]></programlisting>
|
||||
|
||||
<para>
|
||||
At runtime, you just instantiate <literal>HashMap</literal>s and use
|
||||
the Hibernate entity name to refer to a particular type:
|
||||
|
||||
Note that even though associations are declared using target class names,
|
||||
the target type of an associations may also be a dynamic entity instead
|
||||
of a POJO.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
After setting the default entity mode to <literal>dynamic-map</literal>
|
||||
for the <literal>SessionFactory</literal>, we can at runtime work with
|
||||
<literal>Map</literal>s of <literal>Map</literal>s:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
Map parent = new HashMap();
|
||||
parent.put("name", "foo");
|
||||
parent.put("address", "bar");
|
||||
Transaction tx = s.beginTransaction();
|
||||
Session s = openSession();
|
||||
|
||||
Map child = new HashMap();
|
||||
child.put("name", "fooTwo");
|
||||
child.put("address", "barTwo");
|
||||
child.put("parent", parent);
|
||||
// Create a customer
|
||||
Map david = new HashMap();
|
||||
david.put("name", "David");
|
||||
|
||||
s.save("TestMap", parent);
|
||||
t.commit();
|
||||
// Create an organization
|
||||
Map foobar = new HashMap();
|
||||
foobar.put("name", "Foobar Inc.");
|
||||
|
||||
// Link both
|
||||
david.put("organization", foobar);
|
||||
|
||||
// Save both
|
||||
s.save("Customer", david);
|
||||
s.save("Organization", foobar);
|
||||
|
||||
tx.commit();
|
||||
s.close();]]></programlisting>
|
||||
|
||||
<para>
|
||||
|
@ -380,6 +415,40 @@ s.close();]]></programlisting>
|
|||
allowing to add a proper domain model implementation on top later on.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Entity representation modes can also be set on a per <literal>Session</literal>
|
||||
basis:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[Session dynamicSession = pojoSession.getSession(EntityMode.MAP);
|
||||
|
||||
// Create a customer
|
||||
Map david = new HashMap();
|
||||
david.put("name", "David");
|
||||
dynamicSession.save("Customer", david);
|
||||
...
|
||||
dynamicSession.flush();
|
||||
dynamicSession.close()
|
||||
...
|
||||
// Continue on pojoSession
|
||||
]]></programlisting>
|
||||
|
||||
|
||||
<para>
|
||||
Please note that the call to <literal>getSession()</literal> using an
|
||||
<literal>EntityMode</literal> is on the <literal>Session</literal> API, not the
|
||||
<literal>SessionFactory</literal>. That way, the new <literal>Session</literal>
|
||||
shares the underlying JDBC connection, transaction, and other context
|
||||
information. This means you don't have tocall <literal>flush()</literal>
|
||||
and <literal>close()</literal> on the secondary <literal>Session</literal>, and
|
||||
also leave the transaction and connection handling to the primary unit of work.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
More information about the XML representation capabilities can be found
|
||||
in <xref linkend="xml"/>.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<para>
|
||||
|
|
|
@ -1,42 +1,45 @@
|
|||
<chapter id="xml">
|
||||
|
||||
<title>XML Mapping</title>
|
||||
|
||||
<emphasis>
|
||||
Note that this is an experimental feature in Hibernate 3.0 and is under
|
||||
extremely active development.
|
||||
</emphasis>
|
||||
|
||||
<sect1 id="xml-intro" revision="1">
|
||||
<title>Working with XML data</title>
|
||||
|
||||
<para>
|
||||
Hibernate lets you work with persistent XML data in much the same way
|
||||
you work with persistent POJOs. A parsed XML tree can be thought of
|
||||
as just another way to represent the relational data at the object level.
|
||||
as just another way to represent the relational data at the object level,
|
||||
instead of POJOs.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Hibernate supports dom4j as API for manipulating XML trees. You can write
|
||||
queries that retrieve dom4j trees from the database and have any
|
||||
modification you make to the tree automatically synchronized to the
|
||||
database. You can even take an XML document, parse it using dom4j, and
|
||||
write it to the database with any of Hibernate's basic operations:
|
||||
<literal>persist(), saveOrUpdate(), merge(), delete(), replicate()</literal>
|
||||
(merge is not yet supported in Hibernate 3.0rc1).
|
||||
(merging is not yet supported).
|
||||
</para>
|
||||
|
||||
|
||||
<para>
|
||||
This feature has many applications including data import/export,
|
||||
externalization of entity data via JMS or SOAP and XSLT-based reporting.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An single mapping may be used to simultaneously map properties of a class
|
||||
A single mapping may be used to simultaneously map properties of a class
|
||||
and nodes of an XML document to the database, or, if there is no class to map,
|
||||
it may be used to map just the XML.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis>
|
||||
Note that this is an experimental feature in Hibernate 3.0 and is under
|
||||
extremely active development.
|
||||
</emphasis>
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<sect2 id="xml-intro-mapping">
|
||||
<title>Specifying XML and class mapping together</title>
|
||||
|
||||
<para>
|
||||
Here is an example of mapping a POJO and XML simultaneously:
|
||||
</para>
|
||||
|
@ -64,7 +67,8 @@
|
|||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Specifying just an XML mapping</title>
|
||||
<title>Specifying only an XML mapping</title>
|
||||
|
||||
<para>
|
||||
Here is an example where there is no POJO class:
|
||||
</para>
|
||||
|
@ -94,19 +98,21 @@
|
|||
</class>]]></programlisting>
|
||||
|
||||
<para>
|
||||
This mapping will let us access the data as a dom4j tree, or as a graph of
|
||||
This mapping allows you to access the data as a dom4j tree, or as a graph of
|
||||
property name/value pairs (java <literal>Map</literal>s). The property names
|
||||
are purely logical constructs that may be referred to in HQL queries.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="xml-mapping" revision="1">
|
||||
<title>XML mapping metadata</title>
|
||||
|
||||
<para>
|
||||
Many Hibernate mapping elements accept the <literal>node</literal> attribute.
|
||||
This let's us specify the name of an XML attribute or element that holds the
|
||||
This let's you specify the name of an XML attribute or element that holds the
|
||||
property or entity data. The format of the <literal>node</literal> attribute
|
||||
must be one of the following:
|
||||
</para>
|
||||
|
@ -141,7 +147,7 @@
|
|||
|
||||
<para>
|
||||
You should be careful not to leave <literal>embed-xml="true"</literal> for
|
||||
too many associations, since XMl does not deal well with circularity!
|
||||
too many associations, since XML does not deal well with circularity!
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[<class name="Customer"
|
||||
|
@ -202,7 +208,7 @@
|
|||
</customer>]]></programlisting>
|
||||
|
||||
<para>
|
||||
If we set <literal>embed-xml="true"</literal> on the <literal><one-to-many></literal>
|
||||
If you set <literal>embed-xml="true"</literal> on the <literal><one-to-many></literal>
|
||||
mapping, the data might look more like this:
|
||||
</para>
|
||||
|
||||
|
@ -230,14 +236,14 @@
|
|||
<title>Manipulating XML data</title>
|
||||
|
||||
<para>
|
||||
Now that we have mapped our entities to XML, we want to be able to read and
|
||||
update XML documents in our application. We do this by obtaining a dom4j session:
|
||||
Let's rearead and update XML documents in the application. We do this by
|
||||
obtaining a dom4j session:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[Document doc = ....;
|
||||
|
||||
Session session = factory.openSession();
|
||||
Session dom4jSession = session.openSession(EntityMode.DOM4J);
|
||||
Session dom4jSession = session.getSession(EntityMode.DOM4J);
|
||||
Transaction tx = session.beginTransaction();
|
||||
|
||||
List results = dom4jSession
|
||||
|
@ -253,7 +259,7 @@ tx.commit();
|
|||
session.close();]]></programlisting>
|
||||
|
||||
<programlisting><![CDATA[Session session = factory.openSession();
|
||||
Session dom4jSession = session.openSession(EntityMode.DOM4J);
|
||||
Session dom4jSession = session.getSession(EntityMode.DOM4J);
|
||||
Transaction tx = session.beginTransaction();
|
||||
|
||||
Element cust = (Element) dom4jSession.get("Customer", customerId);
|
||||
|
|
Loading…
Reference in New Issue