Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 6082
  • Last Modified:

Hibernate m-o cascaded relation, cannot get it to work.

Hi,

I am using the following declaration:
This is the only relationship declared at all. Single direction one-to-one.

I have also tried:
     * @hibernate.many-to-one column="SL_Contact_ID" unique="true" cascade="all" not-null="true"

Which doesn't work either.
Basically, the stakeholder table has a one to one relationship to contact through contact_id on the stakeholder table. The relationship can be interpreted as one to one or one to many. All I need is one single successful update that cascades. I don't actually care how the relationship is declared as long as the child gets saved first, which does not seem to happen.


    /**
     * public access for SL Contact ID
     * This method dereferences an instance of SLContact.
     * @hibernate.one-to-one column="SL_Contact_ID" constrained="true" cascade="save-update"
     * @return The related instance of SLContact.
     */
     public SLContact getSLContact() {
         return slContact;
     }
         
This does not cascade.
Given the code below

        c = new SLContact();
        SHStakeholder sh = new SHStakeholder();
        sh.setSHQuantumNbr("TESTQUANT");
        sh.setSLContact(c);
        c.setFirstname("Craig");
        c.setLastname("Main");
        c.setMiddlename("Richard");        
        c.setAccount("PPS");
        c.setSeccodeid("PPS");
        Object om = session.save(sh);
        System.out.println(om);
       session.save(c);
            session.flush();
0
cmain
Asked:
cmain
  • 4
  • 4
  • 2
1 Solution
 
cmainAuthor Commented:
Correction,

Leave out the session.save(c) statement.
I am trying to save with just session.save(sh);
I am trying to get the code to work with just one save, namely the parent save. It must cascade to the child objects.

Regards
Craig
0
 
TimYatesCommented:
I'm not sure if http://www.hibernate.org/155.html will help you out or not...

Hope so...  The hibernate documentation han be fairly hard work sometimes...especially when you want to do something like this... :-(
0
 
cmainAuthor Commented:
Hi Tim,

The documentation is aweful.
What I am trying to do is about as simple as it gets though.
I have a field in table A that references a child in table B.

I want a simple unidirectional relationship that updates the child first. It appears not to work.
There is a note in the link you sent me about many-to-one always being inverse=false, I am still trying to figure out the implication of that statement.

Regards
Craig
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
TimYatesCommented:
Again, not sure this helps (I have used hibernate once, but my database was too big and relied on loading subsets of child nodes -- hibernate insisted on loading all children, which took too long, so I went back to straight SQL and a transfer object) but there is this which seems to look at a lot of the possibilities:

http://blog.ideoplex.com/software/2004/05/21.html
0
 
drjustinCommented:
This is simple one-to-many relation (you can also make it one-to-one, but you must be careful here - the same id should be applied ... for more info read Hibernate's documentation).

This worked for me:
<hibernate-mapping>
    <class
        name="com.Foo"
        table="foo"
    >

        <id
            name="foo_id"
            column="foo_id"
            type="int"
            unsaved-value="0"
        >
            <generator class="native">
            </generator>
        </id>

        <many-to-one
            name="source"
            class="Source"
            cascade="save-update"
            outer-join="auto"
            column="fint"
            not-null="true"
        />

    </class>

</hibernate-mapping>

                Source source = new Source();
                Foo foo = new Foo();
                source.setSource_server("foo_bar2");
                foo.setSource(source);
                session.save(foo); //saving only foo!

It inserted new row into foo table and also into source table - as one should expect.

btw: tag many-to-one has no 'inverse' attribute
0
 
cmainAuthor Commented:
Mine looks like this

        <many-to-one
            name="SLContact"
            class="com.palantir.db.SLContact"
            cascade="save-update"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            column="SL_Contact_ID"
            not-null="true"
        />

I have tried this

        <many-to-one
            name="SLContact"
            class="com.palantir.db.SLContact"
            cascade="save-update"
            outer-join="auto"
            column="SL_Contact_ID"
            not-null="true"
        />

I get the same result.
It throws a PropertyValueException saying that a not-null property references a null or transient value.

From the code, you can see that I am setting the contact to c, which is a new one.


        SLContact c = new SLContact();
        SHStakeholder sh = new SHStakeholder();
        sh.setSHQuantumNbr("TESTQUANT");
        sh.setSLContact(c);
        c.setFirstname("Craig");
        c.setLastname("Main");
        c.setMiddlename("Richard");        
        c.setAccount("PPS");
        c.setSeccodeid("PPS");
        Object om = session.save(sh);
0
 
drjustinCommented:
"It throws a PropertyValueException saying that a not-null property references a null or transient value"
 - http://www.hibernate.org/hib_docs/api/net/sf/hibernate/PropertyValueException.html

Did you check all your hbm.xml's if upper criteria is satisfied - no null objects, ...?
What are your id generators (for STContact and SHStakeholder) - maybe Hibernate still 'believes' that SLContact is not saved since it has the same id as your unsaved declaration.

<id
        ...
        unsaved-value="any|none|null|id_value"  
        ...


        <generator class="generatorClass"/>
</id>

But you see that cascading is used here - so calling save just on sh it is going to save all cascading children.
0
 
cmainAuthor Commented:
It is wierd.
If I run the code with not-null as false, then it works. (I changed the database to accomodate this test).
It issues two insert statements, and then an update - all groovy, except the the database is now incorrect.
(@hibernate.many-to-one column="SL_Contact_ID" cascade="save-update" not-null="false")

If I mark the relationship as not-null
(@hibernate.many-to-one column="SL_Contact_ID" cascade="save-update" not-null="true")

Then I get the exception.
I have attached the trace. The contact does get inserted, the generated value is returned 653502.
The generated value is not put into the insert statement for the SHStakeholder instance. The cascades are done, but the cascaded key value is not transferred.

2004-11-25 10:40:00,520 DEBUG [net.sf.hibernate.impl.SessionFactoryObjectFactory] JNDI lookup: hibernate/HibernateFactory
2004-11-25 10:40:00,520 DEBUG [net.sf.hibernate.impl.SessionFactoryObjectFactory] lookup: uid=8ae496f7006edfbb01006ee2ea170001
2004-11-25 10:40:00,520 DEBUG [net.sf.hibernate.impl.SessionImpl] opened session
2004-11-25 10:40:00,581 DEBUG [net.sf.hibernate.impl.SessionImpl] saving [com.palantir.db.SHStakeholder#<null>]
2004-11-25 10:40:00,581 DEBUG [net.sf.hibernate.impl.SessionImpl] executing insertions
2004-11-25 10:40:00,581 DEBUG [net.sf.hibernate.engine.Cascades] processing cascades for: com.palantir.db.SHStakeholder
2004-11-25 10:40:00,581 DEBUG [net.sf.hibernate.engine.Cascades] cascading to saveOrUpdate()
2004-11-25 10:40:00,581 DEBUG [net.sf.hibernate.impl.SessionImpl] saveOrUpdate() unsaved instance
2004-11-25 10:40:00,681 DEBUG [net.sf.hibernate.impl.SessionImpl] generated identifier: 653502
2004-11-25 10:40:00,681 DEBUG [net.sf.hibernate.impl.SessionImpl] saving [com.palantir.db.SLContact#653502]
2004-11-25 10:40:00,681 DEBUG [net.sf.hibernate.engine.Cascades] done processing cascades for: com.palantir.db.SHStakeholder
2004-11-25 10:40:00,721 ERROR [STDERR] net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: com.palantir.db.SHStakeholder.SLContact

0
 
drjustinCommented:
Here is my log - all looks as it should - first it inserts child, gets its id and then inserts parent. This should be common behaviour. I don't see how you don't get the same.
What Hibernate version are you using? What database?
Set show_sql = true and observe what's going on.
Did you try posting this at Hibernate's forum? Yeah, the traffic there is high and such topics get quickly lost.

'except the the database is now incorrect'
I don't see how it is uncorrect - you still get desired thing - cascaded save. Ok, not to be able to declare not-null is an obstacle.

hibernate.impl.SessionImpl  - opened session
hibernate.transaction.JDBCTransaction  - begin
hibernate.transaction.JDBCTransaction  - current autocommit status:false
hibernate.impl.SessionImpl  - saving [com.Foo#<null>]
hibernate.impl.SessionImpl  - executing insertions
hibernate.engine.Cascades  - processing cascades for: com.Foo
hibernate.engine.Cascades  - cascading to saveOrUpdate()
hibernate.engine.Cascades  - id unsaved-value: 0
hibernate.impl.SessionImpl  - saveOrUpdate() unsaved instance
hibernate.impl.SessionImpl  - saving [com.generalynx.gema.utils.data.Source#<null>]
hibernate.impl.SessionImpl  - executing insertions
hibernate.persister.EntityPersister  - Inserting entity: com.generalynx.gema.utils.data.Source (native id)
hibernate.impl.BatcherImpl  - about to open: 0 open PreparedStatements, 0 open ResultSets
hibernate.SQL  - insert into source (source_name, source_desc, source_server, source_database, source_username, source_password, source_sender, source_type, source_param) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
rce (source_name, source_desc, source_server, source_database, source_username, source_password, source_sender, source_type, source_param) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
hibernate.impl.BatcherImpl  - preparing statement
hibernate.persister.EntityPersister  - Dehydrating entity: [com.generalynx.gema.utils.data.Source#<null>]
hibernate.type.StringType  - binding null to parameter: 1
hibernate.type.StringType  - binding null to parameter: 2
hibernate.type.StringType  - binding 'foo_bar2' to parameter: 3
hibernate.type.StringType  - binding null to parameter: 4
hibernate.type.StringType  - binding null to parameter: 5
hibernate.type.StringType  - binding null to parameter: 6
hibernate.type.StringType  - binding null to parameter: 7
hibernate.type.IntegerType  - binding '0' to parameter: 8
hibernate.type.StringType  - binding null to parameter: 9
hibernate.persister.AbstractEntityPersister  - Natively generated identity: 21
hibernate.impl.BatcherImpl  - done closing: 0 open PreparedStatements, 0 open ResultSets
hibernate.impl.BatcherImpl  - closing statement
hibernate.engine.Cascades  - done processing cascades for: com.Foo
hibernate.persister.EntityPersister  - Inserting entity: com.Foo (native id)
hibernate.impl.BatcherImpl  - about to open: 0 open PreparedStatements, 0 open ResultSets
hibernate.SQL  - insert into foo (foo_temp, datum, fint) values (?, ?, ?)
 (foo_temp, datum, fint) values (?, ?, ?)
hibernate.impl.BatcherImpl  - preparing statement
hibernate.persister.EntityPersister  - Dehydrating entity: [com.Foo#<null>]
hibernate.type.StringType  - binding null to parameter: 1
hibernate.type.TimestampType  - binding null to parameter: 2
hibernate.type.IntegerType  - binding '21' to parameter: 3
hibernate.persister.AbstractEntityPersister  - Natively generated identity: 6
hibernate.impl.BatcherImpl  - done closing: 0 open PreparedStatements, 0 open ResultSets
hibernate.impl.BatcherImpl  - closing statement
hibernate.engine.Cascades  - processing cascades for: com.Foo
hibernate.engine.Cascades  - done processing cascades for: com.Foo
hibernate.transaction.JDBCTransaction  - commit
hibernate.impl.SessionImpl  - flushing session
hibernate.engine.Cascades  - processing cascades for: com.Foo
hibernate.engine.Cascades  - cascading to saveOrUpdate()
hibernate.impl.SessionImpl  - saveOrUpdate() persistent instance
hibernate.engine.Cascades  - done processing cascades for: com.Foo
hibernate.impl.SessionImpl  - Flushing entities and processing referenced collections
hibernate.impl.SessionImpl  - Processing unreferenced collections
hibernate.impl.SessionImpl  - Scheduling collection removes/(re)creates/updates
hibernate.impl.SessionImpl  - Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects
hibernate.impl.SessionImpl  - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
hibernate.impl.Printer  - listing entities:
hibernate.impl.Printer  - com.Foo{datum=null, foos=null, source=Source#21, foo_temp=null, foo_id=6}
hibernate.impl.Printer  - com.generalynx.gema.utils.data.Source{source_param=null, source_type=0, source_username=null, source_id=21, source_server=foo_bar2, source_desc=null, source_database=null, source_name=null, source_sender=null, source_password=null}
hibernate.impl.SessionImpl  - executing flush
hibernate.impl.SessionImpl  - post flush
hibernate.impl.SessionImpl  - transaction completion
hibernate.impl.SessionImpl  - closing session
hibernate.impl.SessionImpl  - disconnecting session
hibernate.impl.SessionImpl  - transaction completion
0
 
drjustinCommented:
I disagree with 'no points refunded'. My answer holds value for the correct settings (it works for me with no extra settings and this is normal behaviour) and due to no further contact from topic provider I couldn't exactly point to the problem. But the thing is that if you use it as one should, things do behave as expected - they solve this question.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 4
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now