-->
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.  [ 2 posts ] 
Author Message
 Post subject: Join Table Row not Deleted when Removing Non-Owning Entity
PostPosted: Mon Sep 25, 2006 6:42 am 
Newbie

Joined: Sun Sep 24, 2006 10:29 pm
Posts: 2
This is probably just my noob-nees to JPA/Hibernate, but when I remove an Entity that is at the Non-Owning end of a many-to-many relationship the associated rows from the Join table are not removed, and consequently produces a constraint exception in the DB. Whereas when I remove an entity from the Owning end - it does remove the row(s) from the Join table and all is well with the world.

I'm sure it's something simple...

I'm usinng Hibernate 3.2 CR4, Hibernate Annotations 3.2 CR2 and Hibernate Entity Manager 3.2 CR2. DB is Oracle 10g.

Here's the table definitions:

Code:
CREATE TABLE TableOne (
   TableOneId NUMBER (20) NOT NULL,
   data VARCHAR (255) NOT NULL,
   CONSTRAINT PK_TableOne PRIMARY KEY (TableOneId)
   );

CREATE TABLE TableTwo (
   TableTwoId NUMBER (20) NOT NULL,
   data VARCHAR (255) NOT NULL,
   CONSTRAINT PK_TableTwo PRIMARY KEY (TableTwoId)
   );

CREATE TABLE TableOne_TableTwo (
   TableOneId NUMBER (20) NOT NULL,
   TableTwoId NUMBER (20) NOT NULL,
   CONSTRAINT FK_TableOne_TableTwo PRIMARY KEY (TableOneId, TableTwoId)
   );

ALTER TABLE TableOne_TableTwo ADD (CONSTRAINT FK_TableOne_TableTwo_1 FOREIGN KEY (TableOneId) REFERENCES TableOne (TableOneId));
ALTER TABLE TableOne_TableTwo ADD (CONSTRAINT FK_TableOne_TableTwo_2 FOREIGN KEY (TableTwoId) REFERENCES TableTwo (TableTwoId));


Here are the JPA Annoted classes:

Code:
package entity;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;


@Entity()
@Table(name = "TABLEONE", schema = "GREG")
public class TableOne implements Serializable {

   @Id()
   @Column(name = "TABLEONEID", unique = true, nullable = false, precision = 20)
   private Long tableOneId;

   @Basic()
   @Column(name = "DATA", nullable = false, length = 255)
   private String data;

   @ManyToMany()
   @JoinTable(name = "TABLEONE_TABLETWO", joinColumns = { @JoinColumn(name = "TABLEONEID", referencedColumnName = "TABLEONEID", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "TABLETWOID", referencedColumnName = "TABLETWOID", nullable = false) })
   private Set<TableTwo> TableTwos;

   public TableOne() {
   }

   public String getData() {
      return data;
   }

   public void setData(String data) {
      this.data = data;
   }

   public Long getTableOneId() {
      return tableOneId;
   }

   public void setTableOneId(Long tableOneId) {
      this.tableOneId = tableOneId;
   }

   public Set<TableTwo> getTableTwos() {
      return TableTwos;
   }

   public void setTableTwos(Set<TableTwo> tableTwos) {
      TableTwos = tableTwos;
   }

}


Code:
package entity;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;


@SuppressWarnings("serial")
@Entity
@Table(name = "TABLETWO")
public class TableTwo implements Serializable {

   @Id
   @Column(name="TABLETWOID", unique=true, nullable=false , precision=20)
   private Long tableTwoId;
   
   @Basic
   @Column(name="DATA", nullable=false, length=255)
   private String data;
   
   @ManyToMany(mappedBy="TableTwos")
   private Set<TableOne> TableOnes;
   
   public TableTwo() {
   }
   
   public String getData() {
      return data;
   }
   public void setData(String data) {
      this.data = data;
   }
   public Set<TableOne> getTableOnes() {
      return TableOnes;
   }
   public void setTableOnes(Set<TableOne> tableOnes) {
      TableOnes = tableOnes;
   }
   public Long getTableTwoId() {
      return tableTwoId;
   }
   public void setTableTwoId(Long tableTwoId) {
      this.tableTwoId = tableTwoId;
   }
   
}


And here is a JUnit test (the second test fails). Note that the DB is populated with matching rows in each of TableOne and TableTwo:

Code:
package test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import junit.framework.TestCase;
import entity.TableOne;
import entity.TableTwo;

public class TableTest extends TestCase {

   EntityManagerFactory emf;

   EntityManager em;

   @Override
   protected void setUp() throws Exception {
      emf = Persistence.createEntityManagerFactory("Test");
      em = emf.createEntityManager();
   }

   public void testRemoveTableOne() {

      EntityTransaction tx = em.getTransaction();
      tx.begin();

      TableOne tableOne = em.find(TableOne.class, 1L);
      em.remove(tableOne);

      tx.commit();
   }

   public void testRemoveTableTwo() {

      EntityTransaction tx = em.getTransaction();
      tx.begin();

      TableTwo tableTwo = em.find(TableTwo.class, 2L);
      em.remove(tableTwo);

      tx.commit();
   }

}


And finally the persistence.xml:

Code:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
   version="1.0">
   <persistence-unit name="Test" transaction-type="RESOURCE_LOCAL">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <class>entity.TableOne</class>
      <class>entity.TableTwo</class>
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9Dialect" />
         <property name="hibernate.connection.driver_class"
            value="oracle.jdbc.driver.OracleDriver" />
         <property name="hibernate.connection.username" value="user" />
         <property name="hibernate.connection.password" value="password" />
         <property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
         <property name="hibernate.cache.provider_class"
            value="org.hibernate.cache.HashtableCacheProvider" />
         <property name="hibernate.show_sql" value="true" />
         <property name="hibernate.format_sql" value="true" />
         <property name="hibernate.use_sql_comments" value="true" />
      </properties>
   </persistence-unit>
</persistence>


Any help much appreciated.


Top
 Profile  
 
 Post subject: Re: Join Table Row not Deleted when Removing Non-Owning Enti
PostPosted: Thu Sep 28, 2006 10:59 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
GregFraser wrote:
This is probably just my noob-nees to JPA/Hibernate, but when I remove an Entity that is at the Non-Owning end of a many-to-many relationship the associated rows from the Join table are not removed, and consequently produces a constraint exception in the DB. Whereas when I remove an entity from the Owning end - it does remove the row(s) from the Join table and all is well with the world.


This is the expected behavior, you must take care of your object model consistency.
Note that if this model were not persisted, you would apply the changes on both sides of the relationship in your object model, so do it :-)

_________________
Emmanuel


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