-->
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.  [ 5 posts ] 
Author Message
 Post subject: Problems using HQL with Cascaded Delete
PostPosted: Sat Aug 19, 2006 6:39 am 
Newbie

Joined: Fri Aug 18, 2006 9:11 am
Posts: 7
Hi,

I have defined a many to many relationship between two classes, viz.
Event and Person (defined in a separate database table person_event).
The code of these classes is listed at the end.

When I tried using HQL query to delete an event, it came up with an exception. What I don't understand is that delete(event) works, but the HQL query doesnt work and throws the foreign key violation exception.

-Abhishek

Below is the code excerpt.

String hql = "delete from Event where title = 'Your Event'";
query = session.createQuery(hql);
int rowCount = query.executeUpdate();
System.out.println("Rows affected: " + rowCount);
session.close();

And the EXCEPTION it caused.

Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on "events" violates foreign key constraint "fkecd7dd303b90a48b" on "person_event"

at org.postgresql.util.PSQLException.parseServerError(PSQLException.java:139)
at org.postgresql.core.QueryExecutor.executeV3(QueryExecutor.java:152)
at org.postgresql.core.QueryExecutor.execute(QueryExecutor.java:100)
at org.postgresql.core.QueryExecutor.execute(QueryExecutor.java:43)
at org.postgresql.jdbc1.AbstractJdbc1Statement.execute(AbstractJdbc1Statement.java:517)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:50)
at org.postgresql.jdbc1.AbstractJdbc1Statement.executeUpdate(AbstractJdbc1Statement.java:273)
at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:75)
... 18 more

Event and Person Class

package test;

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

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name="events")
public class Event implements Serializable {
private Long id;
private String title;
private Date date;

public Event() {
}

@Id @GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}

private void setId(Long id) {
this.id = id;
}

@Temporal(TemporalType.TIMESTAMP)
public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}
private Set<Person> participants = new HashSet<Person>();

@ManyToMany(
cascade={CascadeType.PERSIST},
mappedBy="events",
targetEntity=Person.class
)
public Set<Person> getParticipants() {
return participants;
}

public void setParticipants(Set<Person> participants) {
this.participants = participants;
}
}

package test;

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

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="person")
public class Person implements Serializable {
private Long person_id;
private int age;
private String firstname;
private String lastname;

public Person() {}

@Id @GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return person_id;
}

public void setId(Long id) {
this.person_id = id;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getFirstname() {
return firstname;
}

public void setFirstname(String firstname) {
this.firstname = firstname;
}

public String getLastname() {
return lastname;
}

public void setLastname(String lastname) {
this.lastname = lastname;
}

private Set<Event> events = new HashSet<Event>();

@ManyToMany(
targetEntity=Event.class,
cascade={CascadeType.PERSIST}
)
@JoinTable(
name="person_event",
joinColumns={@JoinColumn(name="person_id")},
inverseJoinColumns={@JoinColumn(name="event_id")})
// Defensive, convenience methods
protected Set<Event> getEvents() {
return events;
}

protected void setEvents(Set<Event> events) {
this.events = events;
}

public void addToEvent(Event event) {
this.getEvents().add(event);
event.getParticipants().add(this);
}

public void removeFromEvent(Event event) {
this.getEvents().remove(event);
event.getParticipants().remove(this);
}
}


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 19, 2006 6:36 pm 
Expert
Expert

Joined: Thu Sep 22, 2005 10:29 am
Posts: 285
Location: Almassera/Valencia/Spain/EU/Earth/Solar system/Milky Way/Local Group/Virgo Supercluster
I think that Hibernate doesn't take care of anything else but the query when using HQL, so it doesn't generate the query to delete the related rows on person_event table when deleting event objects.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 20, 2006 8:17 am 
Regular
Regular

Joined: Fri Aug 18, 2006 2:40 pm
Posts: 51
Location: Metz, France
It seems that the logic behind HQL delete and update is much simpler than the one behind session.delete(object).
So as pepelnm said above, hql delete will not care about your relation table and consequence of deletion.

However if you really want to do your delete using HQL,
you have to tell the Database it must delete row(s) in child table when corresponding row in parent (ie referenced) table are deleted.

example with MySQL:
ADD CONSTRAINT FKECD7DD30898B717B
FOREIGN KEY (event_id)
REFERENCES events(id) ON DELETE CASCADE;

ALTER TABLE person_event
ADD CONSTRAINT FKECD7DD30BDAE051C
FOREIGN KEY (person_id)
REFERENCES person(id) ON DELETE CASCADE;

It just tried it and it works perfect.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 6:03 am 
Newbie

Joined: Fri Aug 18, 2006 9:11 am
Posts: 7
I do not want to generate the database schema by myself. I would want to do that using the annotated classes themselves.


Top
 Profile  
 
 Post subject: The same problem
PostPosted: Thu Dec 07, 2006 3:54 pm 
Newbie

Joined: Thu Dec 07, 2006 3:10 pm
Posts: 1
Location: Here
Hi!
i have the same problem. i'm trying to map 4 entities with typical relationships. one of these is a linktable. I'm working on hibernate 3 over a postgres 8 database.

I've configured the mapping for cascade="delete" in all of the "manytoone" tags and all the "set" tags. when hibernate generates the tables and contraints , the foreing key actions are configured with NO ACTION (delete or update).

When i tried to run a delete operation, the exception is the same (update or delete on "searchcriteriatype" violates foreign key constraint "fkf1081d07efe0a597" on "searchcriteria")....

i've tried changing the foreing key actions manually over the database, but that doesnt matter because hibernate re-generate the tables ..

I'm using session.delete in this attempt, but i tried with a hql query like as "delete...."

this is my mapping for "searchcriteriatype"
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 04-dic-2006 10:34:11 by Hibernate Tools 3.1.0.beta5 -->
<hibernate-mapping>
    <class name="kernel.Searchcriteriatype" table="searchcriteriatype">
        <id name="id" type="integer">
            <column name="pknid" />
            <generator class="sequence" ><param name="sequence">sq_searchcriteriatype</param></generator>
        </id>
        <property name="name" type="string">
            <column name="tname" />
        </property>
        <set name="searchcriterias" inverse="true" cascade="delete">
            <key>
                <column name="fknsearchcriteriatypeid" />
            </key>
            <one-to-many class="kernel.Searchcriteria" />
        </set>
    </class>
</hibernate-mapping>


i'm using a Home class to make this actions, this is the class
Code:
/*
* Archivo: ResourceHome.java
* Hora de Creacion: 14:51:19
* Fecha de Creacion: 05-dic-2006
* Nombre del Proyecto: AVA20071_HistoriaDesarrolloEmpresarialColombiano
* Nombre del Paquete: kernel.home
* Año: 2006
*/
package kernel.home;

import java.util.Collection;
...
import kernel.util.SessionManager;


public class SearchCriteriaTypeHome implements GeneralHome
{

    private static final long serialVersionUID = 1L;

    private Session session;


    public SearchCriteriaTypeHome()
    {
        this.session=SessionManager.getSessionInstance();
    }
    ...
...
    ...
    public void delete(Object vo)
    {
        Searchcriteriatype res=(Searchcriteriatype)vo;
        Transaction tx = this.session.beginTransaction ( );
        this.session.delete ( "kernel.Searchcriteriatype", res );
        tx.commit ( );   
    }

}



that's the other mapping,
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 04-dic-2006 10:34:11 by Hibernate Tools 3.1.0.beta5 -->
<hibernate-mapping>
    <class name="kernel.Searchcriteria" table="searchcriteria" >
        <id name="id" type="integer">
            <column name="pknid" />
            <generator class="sequence" ><param name="sequence">sq_searchcriteria</param></generator>
        </id>
        <property name="name" type="string">
            <column name="tname" />
        </property>
       
        <many-to-one name="searchcriteriatype" class="kernel.Searchcriteriatype" fetch="select" cascade="delete">
            <column name="fknsearchcriteriatypeid" />
        </many-to-one>
        <set name="relResourceSearchcriterias" inverse="true" cascade="delete">
            <key>
                <column name="fknsearchcriteriaid" />
            </key>
            <one-to-many class="kernel.RelResourceSearchcriteria" />
        </set>
    </class>
</hibernate-mapping>


_________________
DarkFulgoreII
-->


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