Reputation: 2471
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
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:
Proposed Model:
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
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
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
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