Archive

Posts Tagged ‘Java’

How to Use Hibernate for Composite Ids and Many-to-Many Mappings

December 29th, 2008

We have a case where most of our tables have composite ids.  This means a key with multiple parts.  While fairly common in the database world, Hibernate appears to prefer that it’s users NOT have complex keys.  The mapping definitions don’t really allow for this to occur (e.g. you can’t specify a generator class in a composite key)

We had thought about generating a single column key (something like a hash of the composite elements), but that just seemed wrong.  I always thought a database should model reality, not some arbitrary manifestation to get a tool to work.

In this example we have two tables that look like this:

Table A
——-
A_NAME VARCHAR(200)
A_ID INT
attributes ….

Table B
——-
B_NAME VARCHAR(200)
B_ID INT
attributes ….

They both have composite ids.  A helper table is generated that provides the many-to-many mappings for the two:

Table AB
——–
A_NAME VARCHAR(200)
A_ID INT
B_NAME VARCHAR(200)
B_ID INT

Using standard Hibernate reverse engineering we end up with the following mappings:

Table A Mapping
—————

<composite-id name=”id” class=”path.to.entity.classes.AId”>
 <key-property name=”aId” type=”integer”>
  <column name=”A_ID” precision=”22″ scale=”0″ />
 </key-property>
 <key-property name=”aName” type=”string”>
  <column name=”A_NAME” length=”12″ />
 </key-property>
</composite-id>

<set name=”bs” table=”table_ab” cascade=”all” inverse=”true”>
 <key>
  <column name=”A_NAME” not-null=”true” />
  <column name=”A_ID” not-null=”true” />
 </key>
 <many-to-many class=”path.to.entity.classes.B”>
  <column name=”B_NAME” />
  <column name=”B_ID” />
 </many-to-many>
</set>  

Table B Mapping
—————

<composite-id name=”id” class=”path.to.entity.classes.BId”>
 <key-property name=”bId” type=”integer”>
  <column name=”B_ID” precision=”22″ scale=”0″ />
 </key-property>
 <key-property name=”bName” type=”string”>
  <column name=”B_NAME” length=”12″ />
 </key-property>
</composite-id>

<!– CRITICAL - Only one side can have inverse=true, the other must have inverse=false –>
<set name=”as” table=”table_ab” cascade=”all” inverse=”false”>
 <key>
  <column name=”B_NAME” not-null=”true” />
  <column name=”B_ID” not-null=”true” />
 </key>
 <many-to-many class=”path.to.entity.classes.A”>
  <column name=”A_NAME” />
  <column name=”A_ID” />
 </many-to-many>
</set>  

Table AB Mapping
—————-

<many-to-one name=”a” class=”path.to.entity.classes.A” update=”false” insert=”false” fetch=”select”>
 <column name=”A_NAME” not-null=”true” />
 <column name=”A_ID” not-null=”true” />
</many-to-one>
<many-to-one name=”b” class=”path.to.entity.classes.B” update=”false” insert=”false” fetch=”select”>
 <column name=”B_NAME” not-null=”true” />
 <column name=”B_ID” not-null=”true” />
</many-to-one>

Be sure to note use of the inverse attribute in the A and B mappings: only one side of a many-to-many can be the ‘owner’ of the relationship.  The owner is denoted with inverse=true setting.  The other side of a many-to-many MUST be inverse=false.  It is completely arbitrary which is the owner, but Hibernate will not work unless there is only one.

So, once the mapping is cleared up we produce fairly normal Java code to create a many-to-many relation:

A a = new A();
a.setXYZZY(”various attributes”);
AId aid = new AId();
aid.setPKPart1(”string”);
aid.setPKPart2(4);           
a.setId(aid);

session.save(a)

B b = new B();
b.setXYZZY(”various attributes”);
BId bid = new BId();
bid.setPKPart1(”string”);
bid.setPKPart2(12);           
b.setId(bid);

session.save(b)

a.getBs().add(b);
session.saveOrUpdate(a);

b.getAs().add(a);
session.saveOrUpdate(b)

session.flush();

Just to be sure, note we are setting the composite id fields manually.  In Oracle this can be done by accessing a Sequence.  Other databases have built-in row ids.

Uncategorized ,

Calling an Oracle Stored Procedure from Hibernate

November 26th, 2008

After looking at several posts on the Internet that had various degrees of correctness we finally got this to work. So I thought it would be good to share. In the specific case we were using a stored procedure to access a sequence number (yes, it is outside of Hibernate’s cachable domain).

First, we place the stored procedure definitions inside of a new mapping file:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<sql-query name="getNextSequence" callable="true">
<return-scalar column="NextVal" type="integer"/>
{ call get_next_sequence(?,:tableName) }
</sql-query>
</hibernate-mapping>

Notes:
- the first argument of the stored procedure is actually an OUT parameter from Oracle.
- the actual name of the output ‘column’ must be specified in the return-scalar field

Then the Java code becomes pretty standard:

Session session = TestHibernateSessionFactory.getSession();
Query query = session.getNamedQuery("getNextSequence");
query.setString("tableName", "Table_X");
Object result = query.uniqueResult();
System.out.print(result);

Uncategorized

Eclipse Would Probably Work Better If It Was Written in C#

May 19th, 2008

While I think they did an admirable job coming up with such a rich UI product in Java, the inherent problems of Java attempting to do cool UI is apparent after any use:  the single thread for running the UI and the almost completely random garbage collection completely croaks my installation every few minutes of coding.

I also would expect some of the UI transitions to work much cleaner as well.  Again, because Java uses a standardized layout model, Windows wouldn’t.

I know it’s heresy: how can you give up write once?  Easy, give me something that works all the time.

Uncategorized

Debugging with Java Spring

March 30th, 2008

Ok, so the Spring Framework allows for a high level of code re-use.  Great.

You use simple XML files to layout the flow of applications in Spring.  This allows for easy configuration of systems.  Great.

You now have a high amount of very atomic code/routines that are put together as needed to implement specific functions.  However, if something goes wrong you can not easily find the problem.  Again, due to the large amount of atomic, small routines that have been pasted together.

Log files are likely useless, as they will point out what happens at the lower level.

The only thing we have found is to log ‘events’ as specially executed code functions at the XML, config layer so we trap the higher level functions attempted to be performed at a specific time.

Other ideas would be great.

Uncategorized , ,

Java Spring Framework

March 3rd, 2008

We have been (completely) rewriting a fairly large Java app using the Spring framework.  One of the developers had previous experience that became the core for the new system.

As one of the developers working on the existing systems I have subsequently been added on to the swarm working on the new app.

At first look, Spring reminds you of older IBM configuration files: every step is laid out in an XML file.  I guess that works, as most systems are very XML cogniscent.  I was somewhat overwhelmed by the amount of detail, at first.  I had though this to be a very complex undertaking.

Then talking this over with the architect, it became apparent that Spring really just breaks down your code into very atomic units.  What is at first overwhelming becomes more apparent to be a complete specification for an application: every step, function is laid out in explicit detail.

That becomes tha ‘Aha’ moment.  Any developed code fits into the xml ‘path’ of the application.  I still think it’s amazing seeing that much of the guts of an application laid out so cleanly.

Uncategorized ,