Announcement Announcement Module
Collapse
No announcement yet.
Association table not filled in on parents update Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Association table not filled in on parents update

    Hi,

    I have those 3 tables :
    FONCTION
    id_fonction integer not null,
    lib varchar,
    primary key id_fonction;

    ROLE
    id_role integer not null,
    lib varchar,
    primary key id_role;

    FONCTION_ROLE
    id_fonction_role integer not null,
    id_fonction integer not null,
    id_role integer not null,
    primary key (id_fonction_role);

    My mapping is this :
    Code:
    <hibernate-mapping package="org.myorg.vo" default-lazy="false">
    	<class name="FonctionVO"
    		table="FONCTION" dynamic-update="true" lazy="false">
    		<id name="id" column="FONCTION_ID">
    			<generator class="increment" />
    		</id>
    		<property name="lib" column="FONCTION_LIB" />
    		
    		<set name="roles" table="FONCTION_ROLE" inverse="true" lazy="false" >
    		    <key column="FONCTION_ID"/>
    		    <many-to-many column="ROLE_ID" class="RoleVO" />
    		</set>
    	</class>
    </hibernate-mapping>
    Code:
    <hibernate-mapping package="org.myorg.vo" default-lazy="false">
    	<class name="RoleVO"
    		table="ROLE" dynamic-update="true" lazy="false">
    		<id name="id" column="ROLE_ID">
    			<generator class="increment" />
    		</id>
    		<property name="lib" column="ROLE_LIB" />
    		
    		<set name="fonctions" table="FONCTION_ROLE" inverse="true" lazy="false">
    		    <key column="ROLE_ID"/>
    		    <many-to-many column="FONCTION_ID" class="FonctionVO"/>
    		</set>
    	</class>
    </hibernate-mapping>
    My Java classes :
    Code:
    public class FonctionVO {
    	private long id;
    	private String lib;
    	private Set<RoleVO> roles = new HashSet<RoleVO>();
    
    	public long getId() {
    		return id;
    	}
    	public void setId(long id) {
    		this.id = id;
    	}
    	public String getLib() {
    		return lib;
    	}
    	public void setLib(String lib) {
    		this.lib = lib;
    	}
    	public Set<RoleVO> getRoles() {
    		return roles;
    	}
    	public void setRoles(Set<RoleVO> roles) {
    		this.roles = roles;
    	}
    	public void addRole(RoleVO role) {
    	    role.getFonctions().add(this);
    	    this.getRoles().add(role);
    	}
    	
    }
    Code:
    public class RoleVO {
    	private long id;
    	private String lib;
    	private Set<FonctionVO> fonctions = new HashSet<FonctionVO>();
    	
    	public long getId() {
    		return id;
    	}
    	public void setId(long id) {
    		this.id = id;
    	}
    	public String getLib() {
    		return lib;
    	}
    	public void setLib(String lib) {
    		this.lib = lib;
    	}
    	public Set<FonctionVO> getFonctions() {
    		return fonctions;
    	}
    	public void setFonctions(Set<FonctionVO> fonctions) {
    		this.fonctions = fonctions;
    	}
    }
    First, is that ok/optimised ? I would like to list roles of a function, list the functions of a role, and add some roles to a specific function.

    To add a role to a function, I do this :
    Code:
    FonctionVO fctOld = fonctionService.getById(idFonction);
        			
        	    	if(rolesSelected != null) {
        	    		for (Iterator iter = rolesSelected.iterator(); iter.hasNext();) {
    						String checkboxId = (String) iter.next();
    						
    						RoleVO roleTmp = roleService.getById(new Long(checkboxId));
    						fctOld.addRole(roleTmp);
    					}
        	    	}
    
        			fonctionService.update(fctOld);
    The "fonctionService" manages the transaction. So there is a getSession, closeSession, ... Perhaps the problem is there... I don't know if it's a problem.

    When I call "fonctionService.update(fctOld);", Hibernate just update the FONCTION table, it does not insert the new roles in FONTION_ROLE table.

    I tried to set cascade="all", but it just updates too all the roles. I tried not-null="true" on the keys mapping, but it does nothing more.

    Does someone has an idea ?

    Thanks a lot.
    Last edited by Ougha; Aug 16th, 2007, 09:32 AM.

  • #2
    Ok my bad, I had set 2 inverse="true".

    I changes the fonction.hmb.xml to this :
    Code:
    <hibernate-mapping package="org.myorg.vo" default-lazy="false">
    	<class name="FonctionVO"
    		table="FONCTION" dynamic-update="true" lazy="false">
    		<id name="id" column="FONCTION_ID">
    			<generator class="increment" />
    		</id>
    		<property name="lib" column="FONCTION_LIB" />
    		
    		<set name="roles" table="FONCTION_ROLE" lazy="false" >
    		    <key column="FONCTION_ID" update="true"/>
    		    <many-to-many column="ROLE_ID" class="RoleVO" />
    		</set>
    	</class>
    </hibernate-mapping>
    And now I have the following error :

    Code:
    Hibernate: update SCHEMACRM.FONCTION set FONCTION_LIB=?, CREATOR_ID=?, CREATION_DATE=?, LAST_EDITOR_ID=?, LAST_EDIT_DATE=?, VALIDE=? where FONCTION_ID=?
    Hibernate: insert into SCHEMACRM.FONCTION_ROLE (FONCTION_ID, ROLE_ID) values (?, ?)
    2007-08-14 11:56:01,073 [http-8080-Processor25] ERROR org.hibernate.util.JDBCExceptionReporter  - DB2 SQL error: SQLCODE: -407, SQLSTATE: 23502, SQLERRMC: TBSPACEID=2, TABLEID=129, COLNO=0
    2007-08-14 11:56:01,073 [http-8080-Processor25] ERROR org.hibernate.event.def.AbstractFlushingEventListener  - Could not synchronize database state with session
    org.hibernate.exception.ConstraintViolationException: could not insert collection rows: [com.abw.valueobject.FonctionVO.roles#1]
    	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
    	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    	at org.hibernate.persister.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:1394)
    	at org.hibernate.action.CollectionUpdateAction.execute(CollectionUpdateAction.java:56)
    	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
    	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
    	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
    	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    	at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:561)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:611)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:581)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:307)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:210)
    	at $Proxy30.update(Unknown Source)
    	at com.myorg.coordination.administration.AdminFonctionsModifAction.saveRole(AdminFonctionsModifAction.java:130)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    (...)
    org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
    	at java.lang.Thread.run(Thread.java:595)
    Caused by: com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -407, SQLSTATE: 23502, SQLERRMC: TBSPACEID=2, TABLEID=129, COLNO=0
    	at com.ibm.db2.jcc.b.zc.d(zc.java:1351)
    	at com.ibm.db2.jcc.a.db.l(db.java:366)
    	at com.ibm.db2.jcc.a.db.a(db.java:64)
    	at com.ibm.db2.jcc.a.r.a(r.java:48)
    	at com.ibm.db2.jcc.a.tb.c(tb.java:266)
    	at com.ibm.db2.jcc.b.ad.Z(ad.java:1666)
    	at com.ibm.db2.jcc.b.ad.d(ad.java:2224)
    	at com.ibm.db2.jcc.b.ad.V(ad.java:521)
    	at com.ibm.db2.jcc.b.ad.executeUpdate(ad.java:504)
    	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
    	at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
    	at org.hibernate.persister.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:1367)
    	... 94 more
    As if Hibernate was trying to insert the role in ROLE table, whereas it already exists. I just want an insert in FONCTION_ROLE table.

    What is the problem ?
    Last edited by Ougha; Aug 14th, 2007, 05:07 AM.

    Comment


    • #3
      No idea ?

      Comment


      • #4
        ok, found it ! After 2 days stucked on it...

        With a bidirectional association, with many-to-many, the primary key of the association table MUST be the 2 primary keys ! Not another primary key.

        So the only change to do was :
        FONCTION_ROLE
        id_fonction integer not null,
        id_role integer not null,
        primary key (id_fonction, id_role);

        instead of

        FONCTION_ROLE
        id_fonction_role integer not null,
        id_fonction integer not null,
        id_role integer not null,
        primary key (id_fonction_role);

        If it could help someone.

        Yataaaaaaaaaaaaaaa !

        Comment

        Working...
        X