Anonymoose
Anonymoose

Reputation: 2471

Delete relationship between objects with HQL

I have 2 Java Classes, one called Definition and one calles Classification. A definition has a list of classifications so 0..n cardinality.

Here is what my object-relational mapping looks like:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.myPackage.Definition" table="definition">
        <id name="id" column="ID" type="java.lang.Long">
            <generator class="increment" />
        </id>        

        <!-- definition will have many to many asscoiations with Classes -->    
        <set name="classes" table="class_definition" cascade="save-update">
            <key column="definition_id" />          
            <many-to-many column="class_id" class="com.myPackage.Classification" foreign-key="fk_class_definition" />
        </set>

    </class>
</hibernate-mapping> 

What I am trying to do now is delete the relationship between the definition and a classification. For example definition X has classification A, B and C and I want to remove the link to classiciation C.

I know how to write a delete query in HQL to delete an object of a class. But I don't know how to delete a value of an attribute of my class.

Can anyone advice?

Upvotes: 3

Views: 780

Answers (4)

user2421763
user2421763

Reputation:

From the question above, I see a problem in the Data-Modeling of the solution. As per the above design, a Definition Object can contain multiple Classification Objects. And, since there is a many-to-many relationship between the two entities, a single Classification Object may associate to multiple Definition Objects.

From the question above, I realize that the Classification Object will not be a transactional entity, but more or less a System-of-Record, which means any changes to it will after all the mappings. Having said that, as per question, attempting to update an attribute of the Classification class to dis-associate the mapping can be problematic! Instead, I propose the below data model.

Current Model: enter image description here

Proposed Model: enter image description here

As per the proposed model, you will not be required to update any attribute of the System-of-record Classification Objects. Instead, your job will be more about deleting & creating new ClassificationMapper Objects. A sample class for Classification will look something as below:


class ClassificationMapper{
     Long definitionId; // Primary key for Definition
     Long classificationId; // Primary key for Classification
}

ClassificationMapper class will have a Many-to-1 composition relation with the Definition class and Many-to-1 association relation with the Classification class.

Upvotes: 2

wastl
wastl

Reputation: 2641

I guess you could use the orphanRemoval=true option, so you would only have to delete the Classiciation instance from the list of classiciations in the Definition instance

Note that this option is only available for 1:n (aka OneToMany) and 1:1 (aka OneToOne) relations, see here

EDIT:

Since you added the fact that you have a ManyToMany relation I would recommend doing something like this:


Definition x = fetchSomeDefinitionFromTheDatabase();
Classification c = x.getClassifications().get(0);
x.getClassifications().remove(c);
definitionDaoOrService.update(x);

Since you have choosen save-update as cascade type, the association between x and c should be gone, but they both still exist.

Upvotes: 0

Predrag Maric
Predrag Maric

Reputation: 24423

I think this could be done using update query, not delete, because you are updating Classification instead of deleting it. Try something like this

update Classification c set c.definition = null where c.definition.id = :defId

EDIT

This is under assumption that the relation between Definition and Classification is bidirectional @OneToMany, as you said in your question, and not many-to-many as your mapping file says.

Upvotes: 0

claudio495h
claudio495h

Reputation: 101

You can read Definition x from the database, do the normal removal process for a Classification and save x again. That should do it.

Upvotes: 0

Related Questions