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.  [ 13 posts ] 
Author Message
 Post subject: Cannot specify on-delete="cascade" for a map or a
PostPosted: Mon Jun 18, 2007 8:06 am 
Newbie

Joined: Fri Jun 15, 2007 7:19 am
Posts: 8
Hibernate version: 3.2.4

Mapping documents:
Code:
<hibernate-mapping>
    <class name="fr.gklopp.test.hibernate3.simple.Document" table="DOCUMENT">
        <id name="id" column="DOCUMENT_ID">
            <generator class="native" />
        </id>

        <map name="titles" table="DOCUMENT_TITLE" lazy="false">
            <key column="DOCUMENT_ID" on-delete="cascade" />
            <index column="LANGUAGE" type="string" />
            <element column="TITLE" type="text" not-null="true" />
        </map>

        <set name="references" table="DOCUMENT_REFERENCE" lazy="false">
            <key column="DOCUMENT_ID" on-delete="cascade" />
            <element type="string" column="REFERENCE" />
        </set>
    </class>
</hibernate-mapping>


Full stack trace of any exception that occurs:
Code:
Initial SessionFactory creation failed.org.hibernate.MappingException: only inverse one-to-many associations may use on-delete="cascade": fr.gklopp.test.hibernate3.simple.Document.references
Exception in thread "main" java.lang.ExceptionInInitializerError
   at fr.gklopp.test.hibernate3.util.HibernateUtil.<clinit>(HibernateUtil.java:17)
   at fr.gklopp.test.hibernate3.simple.DocumentManager.createAndStoreDocument(DocumentManager.java:23)
   at fr.gklopp.test.hibernate3.simple.DocumentManager.main(DocumentManager.java:68)
Caused by: org.hibernate.MappingException: only inverse one-to-many associations may use on-delete="cascade": fr.gklopp.test.hibernate3.simple.Document.references
   at org.hibernate.mapping.Collection.validate(Collection.java:267)
   at org.hibernate.mapping.Set.validate(Set.java:19)
   at org.hibernate.cfg.Configuration.validate(Configuration.java:1106)
   at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1287)
   at fr.gklopp.test.hibernate3.util.HibernateUtil.<clinit>(HibernateUtil.java:13)
   ... 2 more


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

Hello,

I'd like to specify the on-delete="cascade" attribute for a map or for a set with just one element.
When I try to do this, I get the following exception :
Code:
Initial SessionFactory creation failed.org.hibernate.MappingException: only inverse one-to-many associations may use on-delete="cascade"

The on-delete="cascade" attribute can be specified for more complex relationships like one-to-many. But it seems that the case of a simple map or set is not covered.
Am I right?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 18, 2007 8:14 am 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
Hi gklopp,

use this way .
<set name="references" table="DOCUMENT_REFERENCE" lazy="false" cascade="all,delete-orphan">
<key column="DOCUMENT_ID"/>
<one-to-many class="Address"/>
</set>

or if you have different requirement let us know.

_________________
Dharmendra Pandey


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 18, 2007 9:41 am 
Newbie

Joined: Fri Jun 15, 2007 7:19 am
Posts: 8
I want to set the on-delete="cascade" attribute in order to use bulk delete.
I don't want to define a new class (like Address in your example) because it doesn't have its own identity, it is part of the main class.

See the following post : http://forum.hibernate.org/viewtopic.php?t=976291 for more information on what I'd like to do


Top
 Profile  
 
 Post subject: Re:
PostPosted: Mon Jun 18, 2007 4:24 pm 
Senior
Senior

Joined: Tue Jun 12, 2007 4:49 pm
Posts: 127
Location: India
Since you do not have any entity in the element. There is no need to worry about deleting it when the parent gets deleted. It will automatically be deleted.

Just remove all cascade and on-delete options and see if hibernate is able to do what is expected.

Hibernate comes with some intelligent choices of default ;-)

*Do rate if this helps*

cheers!
Jitendra


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 22, 2007 7:38 am 
Newbie

Joined: Fri Jun 15, 2007 7:19 am
Posts: 8
My problem here is that I want to use bulk delete.
The following code enables that :
Code:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
       
        Transaction tx = session.beginTransaction();
       
        String hqlDelete = ;
        session.createQuery("delete Document").executeUpdate();
       
        tx.commit();
        session.close();


With bulk delete, it is your responsibility to manage relationship deletion.
That's why the 'on delete cascade' is set on the database level.

If I don't specify the on-delete="cascade" attribute for the map or set, I get the following exception :

Exception in thread "main"
Code:
org.hibernate.exception.ConstraintViolationException: could not execute update query
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:84)
   at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:396)
   at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:259)
   at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1141)
   at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:94)
   at fr.gklopp.test.hibernate3.simple.DocumentManager.deleteAll(DocumentManager.java:56)
   at fr.gklopp.test.hibernate3.simple.DocumentManager.main(DocumentManager.java:69)
Caused by: java.sql.SQLException: ORA-02292: integrity constraint (REFSED.FK7FD671D42CF818E0) violated - child record found


Gerald


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 23, 2007 4:22 pm 
Senior
Senior

Joined: Tue Jun 12, 2007 4:49 pm
Posts: 127
Location: India
Please remove on-delete="cascade" from the key and put "cascade="all-delete-orphan" in the set and map tags.

This should take care of deleting it during bulk delete.

*Please do rate if it helps*

Regards,
Jitendra


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 25, 2007 7:17 am 
Newbie

Joined: Fri Jun 15, 2007 7:19 am
Posts: 8
The problem remains the same if I add cascade="all-delete-orphan" in the set and map tags

Gerald


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 26, 2007 3:04 pm 
Senior
Senior

Joined: Tue Jun 12, 2007 4:49 pm
Posts: 127
Location: India
I tried this and it seems to go fine:

Code:
   <class name="ClassA">

      <id name="id" column="id" type="long" unsaved-value="0">
          <generator class="increment"/>
      </id>
      
      <property name="note"/>
      
      
      <set name="extStrSet" table="A_set" lazy="false" cascade="all-delete-orphan">
         <key column="a_id"/>
         <element type="string" />
      </set>
      
      <map name="extStrMap" table="A_map" lazy="false" cascade="all-delete-orphan">
         <key column="a_id" />
         <index column="map_index" type="string"/>
         <element type="text" column="map_element"></element>
      </map>

   </class>


And test case as below:
Code:

      ClassA a = new ClassA();
      
      Map<String, String> aMap = new HashMap<String, String>();
      aMap.put("test", "value");
      aMap.put("test1", "value1");
      
      Set<String> aSet = new HashSet<String>();
      
      aSet.add("set1");
      aSet.add("set2");
      
      a.setExtStrMap(aMap);
      a.setExtStrSet(aSet);
      a.setNote("aNote");
      
      Session s = factory.openSession(ds.getConnection());
      
      s.save(a);
      
      a = new ClassA();
      
      aMap = new HashMap<String, String>();
      aMap.put("test", "value");
      aMap.put("test1", "value1");
      
      aSet = new HashSet<String>();
      
      aSet.add("set1");
      aSet.add("set2");
      
      a.setExtStrMap(aMap);
      a.setExtStrSet(aSet);
      a.setNote("aNote");
      
      s.save(a);
      
      s.flush();
      s.close();
      
      
      s = factory.openSession(ds.getConnection());
      System.out.println(s.createQuery("delete ClassA").executeUpdate());
      s.flush();
      s.close();


The above code runs wihout any problem with Hibernate 3.2.4.

*Please rate if it helps*

Regards,
Jitendra


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 28, 2007 7:59 am 
Newbie

Joined: Fri Jun 15, 2007 7:19 am
Posts: 8
This example doesn't go fine with my Oracle database.
That's because a foreign key constraint is set on the A_ID column for tables A_set AND A_map.

This the exception which is thrown when I execute your code :
Code:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute update query
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:84)
   at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:396)
   at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:259)
   at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1141)
   at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:94)
   at fr.gklopp.test.hibernate3.simple.ClassAManager.main(ClassAManager.java:68)
Caused by: java.sql.SQLException: ORA-02292: integrity constraint (REFSED.FK3C0CC5E609D9A08) violated - child record found

   at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
   at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
   at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
   at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
   at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
   at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:966)
   at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1170)
   at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3339)
   at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3423)
   at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:75)


Regards,
Gerald


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 28, 2007 10:55 am 
Senior
Senior

Joined: Tue Jun 12, 2007 4:49 pm
Posts: 127
Location: India
Quote:
..a foreign key constraint is set on the A_ID column for tables A_set AND A_map.


Thats precisely what should happen for the setup to work.

I assume delete is working fine and something else is going wrong. Can't tell what until I can see the code.

Regards,
Jitendra


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 29, 2007 8:21 am 
Newbie

Joined: Fri Jun 15, 2007 7:19 am
Posts: 8
The foreign key is not enough, you have to set a 'on delete cascade' constraint on the foreign key to get this working.

- Example without the 'on delete cascade' constraint set :

Code:
CREATE TABLE CLASSA (
  ID    NUMBER(19) PRIMARY KEY,
  NOTE  VARCHAR2(255 CHAR)
);

CREATE TABLE A_MAP (
  A_ID         NUMBER(19) PRIMARY KEY,
  MAP_INDEX    VARCHAR2(255 CHAR) NOT NULL,
  MAP_ELEMENT  CLOB,
  CONSTRAINT FK1 FOREIGN KEY (A_ID) REFERENCES CLASSA(ID)
);

INSERT INTO CLASSA VALUES(1, 'TEST');
INSERT INTO A_map VALUES(1, 'INDEX1', 'INDEX1_VALUE');

DELETE FROM CLASSA;

The following exception is thrown on the DELETE operation :
Code:
'integrity constraint violated - child record found'


- Example with the 'on delete cascade' constraint set :

Code:
CREATE TABLE CLASSA (
  ID    NUMBER(19) PRIMARY KEY,
  NOTE  VARCHAR2(255 CHAR)
);

CREATE TABLE A_MAP (
  A_ID         NUMBER(19) PRIMARY KEY,
  MAP_INDEX    VARCHAR2(255 CHAR) NOT NULL,
  MAP_ELEMENT  CLOB,
  CONSTRAINT FK1 FOREIGN KEY (A_ID) REFERENCES CLASSA(ID) ON DELETE CASCADE
);

INSERT INTO CLASSA VALUES(1, 'TEST');
INSERT INTO A_map VALUES(1, 'INDEX1', 'INDEX1_VALUE');

DELETE FROM CLASSA;

This goes fine.

That's why I want to set the 'on delete cascade' constraint in the Hibernate mapping file

Gerald


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 29, 2007 9:25 am 
Senior
Senior

Joined: Tue Jun 12, 2007 4:49 pm
Posts: 127
Location: India
heyi gklopp,

on-delete="cascade" is not required since we have cascade="all-delete-orphan".

Regards,
Jitendra


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 29, 2007 1:06 pm 
Newbie

Joined: Fri Jun 15, 2007 7:19 am
Posts: 8
cascade="all-delete-orphan" has no effect for a bulk delete.

I'm going to post a jira issue for this problem

Thank you for your help,
Gerald


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