-->
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.  [ 9 posts ] 
Author Message
 Post subject: cascade="none"
PostPosted: Thu Jun 08, 2006 11:11 am 
Newbie

Joined: Mon Mar 06, 2006 7:21 am
Posts: 6
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: 3.05


Code between sessionFactory.openSession() and session.close():

SchedaUtenza suHib = null;
if(checkConcurrency) {
String codTecnicoScheda = su.getCodTecnicoSchedaUtenza();
suHib = (SchedaUtenza) getHibernateTemplate().get(SchedaUtenza.class, codTecnicoScheda);
if( (suHib.getDataModificaRecord() == null) ||
(suHib.getDataModificaRecord().equals(su.getDataModificaRecord())) )
update = true;
else {
String msg = "Aggiornamento non eseguito. Il dato e' gia' stato modificato da un altro utente.";
throw new Exception(msg);
}
}
else {
update = true;
}

if(update) {
su.setDataModificaRecord(new Date());
suHib = (SchedaUtenza) getHibernateTemplate().merge(su);
}

Full stack trace of any exception that occurs:


ERROR [main] - Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at org.hibernate.JDBCException.<init>(JDBCException.java:26)
at org.hibernate.exception.GenericJDBCException.<init>(GenericJDBCException.java:19)
at org.hibernate.exception.ErrorCodeConverter.handledNonSpecificException(ErrorCodeConverter.java:92)
at org.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:80)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:181)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:74)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:69)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:150)
.......

Name and version of the database you are using: Oracle 9

The generated SQL (show_sql=true):
Hibernate: select schedauten0_.COD_TECNICO_SCHEDA_UTENZA as COD1_0_, schedauten0_.DATA_CREAZIONE_RECORD as DATA2_23_0_, schedauten0_.UTENTE_CREAZIONE_RECORD as UTENTE3_23_0_, schedauten0_.DATA_MODIFICA_RECORD as DATA4_23_0_, schedauten0_.UTENTE_MODIFICA_RECORD as UTENTE5_23_0_, schedauten0_.CODICE_CLIENTE_DISTR_ORIGINALE as CODICE6_23_0_, schedauten0_.DESCRIZIONE_SCHEDA_UTENZA as DESCRIZI7_23_0_, schedauten0_.NOTE as NOTE23_0_, schedauten0_.COD_ENTE as COD9_23_0_, schedauten0_.COD_COSTANTE as COD10_23_0_ from DS_SCHEDE_UTENZE schedauten0_ where schedauten0_.COD_TECNICO_SCHEDA_UTENZA=?
Hibernate: select ente0_.COD_ENTE as COD1_0_, ente0_.DATA_MODIFICA_RECORD as DATA2_17_0_, ente0_.UTENTE_MODIFICA_RECORD as UTENTE3_17_0_, ente0_.DES_ENTE as DES4_17_0_, ente0_.COD_CONTROPARTE as COD5_17_0_, ente0_.COD_TIPO_VALUTA as COD6_17_0_, ente0_.COD_GRUPPO_ENTE as COD7_17_0_, ente0_.SOGGETTO_A_IVA as SOGGETTO8_17_0_, ente0_.COEFF_VALUTAZIONE as COEFF9_17_0_ from DS_ENTI ente0_ where ente0_.COD_ENTE=?
Hibernate: select costantemo0_.COD_COSTANTE as COD1_0_, costantemo0_.DATA_MODIFICA_RECORD as DATA2_21_0_, costantemo0_.UTENTE_MODIFICA_RECORD as UTENTE3_21_0_, costantemo0_.DES_COSTANTE as DES4_21_0_, costantemo0_.COD_TIPO_COSTANTE as COD5_21_0_, costantemo0_.FATTORE_CONVERSIONE_1 as FATTORE6_21_0_, costantemo0_.FATTORE_CONVERSIONE_2 as FATTORE7_21_0_, costantemo0_.COD_UNITA_MISURA as COD8_21_0_ from DS_COSTANTI_MODULI_ENERGETICI costantemo0_ where costantemo0_.COD_COSTANTE=?
Hibernate: select unitamisur0_.COD_UNITA_MISURA as COD1_0_, unitamisur0_.DATA_MODIFICA_RECORD as DATA2_19_0_, unitamisur0_.UTENTE_MODIFICA_RECORD as UTENTE3_19_0_, unitamisur0_.DES_UNITA_MISURA as DES4_19_0_ from DS_UNITA_MISURA unitamisur0_ where unitamisur0_.COD_UNITA_MISURA=?
Hibernate: update DS_SCHEDE_UTENZE set DATA_CREAZIONE_RECORD=?, UTENTE_CREAZIONE_RECORD=?, DATA_MODIFICA_RECORD=?, UTENTE_MODIFICA_RECORD=?, CODICE_CLIENTE_DISTR_ORIGINALE=?, DESCRIZIONE_SCHEDA_UTENZA=?, NOTE=?, COD_ENTE=?, COD_COSTANTE=? where COD_TECNICO_SCHEDA_UTENZA=?
Hibernate: update DS_DISTRIBUTORI_UTENZE set COD_TECNICO_SCHEDA_UTENZA=null where COD_TECNICO_SCHEDA_UTENZA=?
ERROR [main] - ORA-01407: impossibile aggiornare ("DATASOFTWARE"."DS_DISTRIBUTORI_UTENZE"."COD_TECNICO_SCHEDA_UTENZA") a NULL

ERROR [main] - ORA-01407: impossibile aggiornare ("DATASOFTWARE"."DS_DISTRIBUTORI_UTENZE"."COD_TECNICO_SCHEDA_UTENZA") a NULL


This is the excerpt of my mapping file:
<hibernate-mapping default-cascade="none">

<class name="com.datasw.gdp2000web.model.utenze.bo.SchedaUtenza" table="DS_SCHEDE_UTENZE">

<id name="codTecnicoSchedaUtenza" type="string" column="COD_TECNICO_SCHEDA_UTENZA"/>

<property name="dataCreazioneRecord" type="timestamp" column="DATA_CREAZIONE_RECORD"/>
<property name="utenteCreazioneRecord" type="string" column="UTENTE_CREAZIONE_RECORD"/>
<property name="dataModificaRecord" type="timestamp" column="DATA_MODIFICA_RECORD"/>

<set name="distributoreUtenza" lazy="true" cascade="none">
<key column="COD_TECNICO_SCHEDA_UTENZA"/>
<one-to-many class="com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza"/>
</set>
...

Although cascade="none" is the default I have showed it but Hibernate try to update the child object.

The Hibernate reference document says:
"You may even use cascade="all" to specify that all operations should be cascaded along the association. The
default cascade="none" specifies that no operations are to be cascaded."




How can i solve my problem?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 09, 2006 12:39 am 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
In the key of the distributoreUtenza <set>, add not-null="true".

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 09, 2006 3:56 am 
Newbie

Joined: Mon Mar 06, 2006 7:21 am
Posts: 6
I've added not-null="true"

<set name="distributoreUtenza" lazy="true" cascade="none">
<key not-null="true" column="COD_TECNICO_SCHEDA_UTENZA"/>
<one-to-many class="com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza"/>
</set>


and this is the result:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [ApplicationContext.xml]: Can't resolve reference to bean 'sessionFactory' while setting property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [dataAccessContext-local.xml]: Initialization of bean failed; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza column: COD_TECNICO_SCHEDA_UTENZA (should be mapped with insert="false" update="false")
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [dataAccessContext-local.xml]: Initialization of bean failed; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza column: COD_TECNICO_SCHEDA_UTENZA (should be mapped with insert="false" update="false")
org.hibernate.MappingException: Repeated column in mapping for entity: com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza column: COD_TECNICO_SCHEDA_UTENZA (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:526)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:544)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:335)
at org.hibernate.mapping.RootClass.validate(RootClass.java:188)
at org.hibernate.cfg.Configuration.validate(Configuration.java:839)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1000)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:800)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:726)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1059)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:363)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:226)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:147)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:176)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:105)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1013)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:824)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:345)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:226)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:147)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:275)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:320)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:87)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:72)
at com.datasw.gdp2000web.model.utenze.test.TestUtenze.<init>(TestUtenze.java:44)
at com.datasw.gdp2000web.model.utenze.test.TestUtenze.main(TestUtenze.java:38)

I've tried add update="false" in the distributoreUtenza <set> key but without result.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 11, 2006 6:46 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
That's a problem in the DistributoreUtenza mapping. Do you have a <property> in that mapping that uses column="COD_TECNICO_SCHEDA_UTENZA"? It's ok to have it in the <id>, but if you also want it in a <property>, you should use a formula, or use insert/update="false".

If you can't get it working, post the mapping.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 12, 2006 6:02 am 
Newbie

Joined: Mon Mar 06, 2006 7:21 am
Posts: 6
This is the DistributoreUtenza's mapping. The COD_TECNICO_SCHEDA_UTENZA is a key-property. I can't specify attributes like insert, update and formula.
...I've thinking about it.

I don't understand because it's so simple specify my behaviour in one-to-one and many-to-one relation but not in one-to-many.
Do you think I make a conceptual mistake about ORM?


Thanks a lot tenwit for your assistance

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping default-cascade="none">

<class name="com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza" table="DS_DISTRIBUTORI_UTENZE">

<composite-id>
<key-property name="codTecnicoSchedaUtenza" type="string" column="COD_TECNICO_SCHEDA_UTENZA"/>
<key-property name="codTecnicoDistributore" type="string" column="COD_TECNICO_DISTRIBUTORE"/>
</composite-id>

<property name="dataCreazioneRecord" type="timestamp" column="DATA_CREAZIONE_RECORD"/>
<property name="utenteCreazioneRecord" type="string" column="UTENTE_CREAZIONE_RECORD"/>

<many-to-one name="tipoOpzioneTariffaria" lazy="true" class="com.datasw.gdp2000web.model.utenze.bo.TipoOpzioneTariffaria" column="COD_TIPO_OPZIONE_TARIFFARIA"/>
<many-to-one name="controparte" insert="true" update="true" lazy="true" class="com.datasw.gdp2000web.model.anagctp.bo.Controparte">
<column name="COD_ENTE_DISTRIBUTORE"/>
<column name="COD_DISTRIBUTORE"/>
</many-to-one>

</class>

</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 12, 2006 5:54 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
That relationship looks to be unidirectional, is that right? I've only ever done this sort of thing in a bidirectional relationship. The bidirectional version of this is given as an example in section 23.4.2, "Composite key example" of the refdocs. I think that the reverse many-to-one (mapped with insert="false "update="false") is necessary so that hibernate knows that the one-column key from SchedaUtenza maps to just one of the two key columns in DistributoreUtenza.

So I think that your options are either to add in the inverse many-to-one from DistributoreUtenza to SchedaUtenza, or to change the key in DistributoreUtenza to be just the COD_TECNICO_DISTRIBUTORE column. Of course, that second option only works if the column is unique, so you may have to add in the many-to-one.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 13, 2006 5:46 am 
Newbie

Joined: Mon Mar 06, 2006 7:21 am
Posts: 6
I've tried define a many-to-one association in the DistributoreUtenza's mapping like this:

<many-to-one name="schedaUtenza" insert="false" update="false" not-null="true" cascade="none" lazy="true" class="com.datasw.gdp2000web.model.utenze.bo.SchedaUtenza" column="COD_TECNICO_SCHEDA_UTENZA"/>

...and add not-null="true" in the SchedaUtenza's mapping:

<set name="distributoreUtenza" lazy="true" cascade="none">
<key not-null="true" column="COD_TECNICO_SCHEDA_UTENZA"/>
<one-to-many class="com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza"/>
</set>

When I run my application, this Exception rise immediatly:

org.hibernate.MappingException: Repeated column in mapping for entity: com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza column: COD_TECNICO_SCHEDA_UTENZA (should be mapped with insert="false" update="false")


Reading the Hibernate reference 3.0.5 pdf version, I've founded this in section "2.3.6. Working bi-directional links"

...
What about the inverse mapping attribute? For you, and for Java, a bi-directional link is simply a matter of setting
the references on both sides correctly. Hibernate however doesn't have enough information to correctly arrange
SQL INSERT and UPDATE statements (to avoid constraint violations), and needs some help to handle bidirectional
associations properly. Making one side of the association inverse tells Hibernate to basically ignore
it, to consider it a mirror of the other side. That's all that is necessary for Hibernate to work out all of the issues
when transformation a directional navigation model to a SQL database schema. The rules you have to remember
are straightforward: All bi-directional associations need one side as inverse. In a one-to-many association
it has to be the many-side, in many-to-many association you can pick either side, there is no difference.


I've modfied my mapping like this:

<set name="distributoreUtenza" inverse="true" lazy="true" cascade="none">
<key not-null="true" column="COD_TECNICO_SCHEDA_UTENZA"/>
<one-to-many class="com.datasw.gdp2000web.model.utenze.bo.DistributoreUtenza"/>
</set>

Now my application start and work fine...YEEEEEEEESSSS!!!

Next I've eliminated the many-to-one association in the DistributoreUtenza...and all continue work fine.

Now I can update my SchedaUtenza property without consider the distributoreUtenza association.
That's I can pass a SchedaUtenza object and set to null the distributoreUtenza Set and Hibernate doesn't consider it.

...but do you think is correct my inverse utilization???

Thanks for the suggest.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 13, 2006 4:55 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Yes, the set should be inverse: the general rule is, if the things in the collection have a lifecycle of their own (i.e. if you are allowed to create them without them being in a set) then any collection that contains them should be mapped inverse="true".

Setting the set to null is probably not a good idea, as I'd imagine that it would set the COD_TECNICO_SCHEDA_UTENZA column to null for all rows in DistributoreUtenza's table that are currently in that SchedaUtenza's set. I might be wrong about that though, as I've never tried it. It's easy to write a test to see what actually happens: do that, and if you're happy with the results, then you have your solution.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 14, 2006 8:59 am 
Newbie

Joined: Mon Mar 06, 2006 7:21 am
Posts: 6
Ok I'll try test the inverse's behavoiur in the next days.

My application can run quietly because in my context the client isn't so free.
He can't update the key-column partially. The application catch those case and it make a warning.


Thank you very much tenwit. Your suggest've been very helpful.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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.