-->
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.  [ 4 posts ] 
Author Message
 Post subject: How to insert an object with associations in one transaction
PostPosted: Wed May 02, 2007 6:48 am 
Newbie

Joined: Tue May 01, 2007 6:50 pm
Posts: 1
Location: Poland
Hey there,
What I am trying to do is inserting an object plus it's one-to-many associated objects in a single transaction. It's important because the object should not exist without the associated objects, so if something goes wrong the whole transaction should be rolled back.

Hibernate version: 3.1

Mapping documents:
Procedure:
Code:
<hibernate-mapping package="com.package">
    <class name="Procedure" table="procedures" schema="public">
        <id name="id" type="int">
            <column name="procedure_id" />
            <generator class="sequence">
                <param name="sequence">
                    procedure_id_seq
                </param>
            </generator>
        </id>
        <set name="procedureParameters" inverse="true" cascade="persist,merge,save-update">
            <key>
                <column name="procedure_id" not-null="true" />
            </key>
            <one-to-many class="ProcedureParameter" />
        </set>
    </class>
</hibernate-mapping>


ProcedureParameter:
Code:
<hibernate-mapping package="com.package">
    <class name="ProcedureParameter" table="procedure_parameters" schema="public">
        <composite-id name="id" class="ProcedureParameterId">
            <key-property name="parameterCode" type="string">
                <column name="parameter_code" length="12" />
            </key-property>
            <key-property name="procedureId" type="int">
                <column name="procedure_id"/>
            </key-property>
        </composite-id>
        <many-to-one name="procedure" class="Procedure" update="false" insert="false" fetch="select">
            <column name="procedure_id" not-null="true" />
        </many-to-one>
        <property name="value" type="string">
            <column name="value" length="250" />
        </property>
        <property name="remarks" type="string">
            <column name="remarks" length="100" />
        </property>
    </class>
</hibernate-mapping>


Objects in question (stubs only):
Procedure:
Code:
public class Procedure {
   private Integer id;
   private Set<ProcedureParameter> procedureParameters = new HashSet<ProcedureParameter>(0);
}

ProcedureParameter:
Code:
public class ProcedureParameter {
   private ProcedureParameterId id;
   private String value;
   private String remarks;

   private Procedure procedure;
}

ProcedureParameterId:
Code:
public class ProcedureParameterId {
   private String parameterCode;
   private Integer procedureId;
}


Normally I would do something like this (everything within one hibernate session):

Code:
BEGIN TRANSACTION 1

Procedure procedure = new Procedure();
HibernateSession.save(procedure);

COMMIT TRANSACTION 1

BEGIN TRANSACTION 2

ProcedureParameter procParam1 = new ProcedureParameter(new ProcedureParameterId("PARAM1", procedure.getId()), "value1", "remark1");
ProcedureParameter procParam2 = new ProcedureParameter(new ProcedureParameterId("PARAM2", procedure.getId()), "value2", "remark2");
procedure.getProcedureParameters().add(procParam1);
procedure.getProcedureParameters().add(procParam2);
// save not needed - cascade will take care of inserting procedure parameters

COMMIT TRANSACTION 2


But as I mentioned before this has to be done in a single transaction. Is there any way to bind ProcedureParameterId.procedureId to Procedure.id so that once created Procedure.id taken from procedure_id_seq would be known "behind the scenes" to ProcedureParameterId.procedureId?
What I would like is something like this:

Code:
BEGIN TRANSACTION
Procedure procedure = new Procedure();   // gets id only at the commit

ProcedureParameter procParam1 = new ProcedureParameter(new ProcedureParameterId("PARAM1", ???), "value1", "remark1");
ProcedureParameter procParam2 = new ProcedureParameter(new ProcedureParameterId("PARAM2", ???), "value2", "remark2");
procedure.getProcedureParameters().add(procParam1);
procedure.getProcedureParameters().add(procParam2);

HibernateSession.save(procedure);

COMMIT TRANSACTION


Any ideas?


Top
 Profile  
 
 Post subject: map differently
PostPosted: Wed May 02, 2007 7:26 am 
Regular
Regular

Joined: Wed Aug 24, 2005 11:49 am
Posts: 63
Don't map the foreign-key from procedureparameter to procedure as an int, but map it as a key-many-to-one.
Then, you can put the 'unsaved' Procedure object in it, and during the commit, Hibernate will take care of the rest.

_________________
Edwin van der Elst
Finalist IT Group


Top
 Profile  
 
 Post subject: Re: map differently
PostPosted: Mon Oct 22, 2007 8:50 pm 
Newbie

Joined: Mon Oct 22, 2007 8:27 pm
Posts: 7
evdelst wrote:
Don't map the foreign-key from procedureparameter to procedure as an int, but map it as a key-many-to-one.
Then, you can put the 'unsaved' Procedure object in it, and during the commit, Hibernate will take care of the rest.


Hi,

When I do that I get: "ids for this class must be manually assigned before calling save():..."!

Is it really possible to do that without first saving the parent object?

Thanks

Christian


Top
 Profile  
 
 Post subject: key-many-to-one
PostPosted: Tue Oct 23, 2007 4:44 am 
Regular
Regular

Joined: Wed Aug 24, 2005 11:49 am
Posts: 63
Shouldn't the key-property be a key-many-to-one ?
(From parameter to procedure)

Edwin


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

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.