-->
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.  [ 10 posts ] 
Author Message
 Post subject: Unidirectional ManyToOne association with Java5 Annotations
PostPosted: Fri Jul 06, 2007 8:14 am 
Newbie

Joined: Fri Jul 06, 2007 7:05 am
Posts: 5
Hi All,

I am using Hibernate 3.2.1 with Java5 annotations and MySQL as database.
In my domain model I have an entity "ApprovalRequest" which has a unidirectional ManyToOne association to an entity "Image".

Code:
public class ApprovalRequest
{
  @ManyToOne
  private Image image;

  ...
}

public class Image
{
...
}


Per default hibernate seems to map this association as foreign key relation resulting in an "image_id" column in my "approvalrequest" table which is perfectly fine. Additionally a foreign key constraint is added to the "image_id" column.

My problem is that I have to delete Image entities which results in org.hibernate.exception.ConstraintViolationException because of the foreign key constraint on the "image_id" column.

Is it possible to instruct hibernate to reset the value of the "image_id" column to null if an "Image" entity is deleted or do I have to handle this in my code?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 06, 2007 9:20 am 
Newbie

Joined: Fri Jul 06, 2007 9:15 am
Posts: 1
Hibernate may be doing many things. Some of them good, some of them crappy. I think you'll need to implement this on your own.


Now bash me. -- Harry


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 06, 2007 10:55 am 
Newbie

Joined: Mon Jul 02, 2007 2:12 pm
Posts: 18
Hi Thomas,

first of all make clear, if Image really is an entity that is referenced by other entities. If not you should think about using a collection of Image's, see @CollectionOfElements.

If you think Image must be an entity you can add nullable = true to your @ManyToOne.

-Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 06, 2007 11:34 am 
Newbie

Joined: Fri Jul 06, 2007 7:05 am
Posts: 5
Hi ThoKes,

thank you for your help.

"Image" is definitly an entity in the system. It is one of the core entities.
And since "Image" is part of a subsystem and "ApprovalRequest" is part of another subsystem the association has to be unidirectional. Therefore there is no easy way in the code to remove the Image from the ApprovalRequest before deleting it.

I'll try the 'nullable=true' option. Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 09, 2007 3:36 am 
Newbie

Joined: Fri Jul 06, 2007 7:05 am
Posts: 5
Sorry ThoKes, but there seems to be no 'nullable' property available for the Annotation @ManyToOne. There is a property 'optional' which could be set to 'true' but has no effect to the generated DB schema.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 09, 2007 1:55 pm 
Newbie

Joined: Mon Jul 02, 2007 2:12 pm
Posts: 18
Hi Thomas,

sorry for being unprecise, I meant nullable attribute of JoinColumn, pls see example below which should be like yours (Fahrzeug2 equal to your Image, referencing Halter2)


@Entity
public class Halter2 {
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
private long id;

@OneToMany (targetEntity = Fahrzeug2.class, mappedBy = "halter", cascade = CascadeType.ALL)
private Set<Fahrzeug2> fahrzeuge;

...
}


@Entity
public class Fahrzeug2 {
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
private long id;

@ManyToOne ( targetEntity = Halter2.class, fetch = FetchType.LAZY)
@JoinColumn (name = "halter_id", nullable= true)
private Halter2 halter;

@Column (name = "kennzeichen")
private String kennzeichen;
...
}

create table Fahrzeug2 (id number(19,0) not null, kennzeichen varchar2(255), halter_id number(19,0), primary key (id))
19:49:43,953 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport: create table Halter2 (id number(19,0) not null, primary key (id))
19:49:44,015 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport: alter table Fahrzeug2 add constraint FK2DFFC4D0F16DC5AE foreign key (halter_id) references Halter2
19:49:44,031 DEBUG org.hibernate.tool.hbm2ddl.SchemaExport: create sequence hibernate_sequence
19:49:44,031 INFO org.hibernate.tool.hbm2ddl.SchemaExport: schema export complete

As you can see, the FK contraint now has no NOT NULL clause and I could delete a row from Fahrzeug2.


-Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 10, 2007 4:33 am 
Newbie

Joined: Fri Jul 06, 2007 7:05 am
Posts: 5
Hi Thomas,

you're right. Your sample is working perfectly. But my problem is that my association is unidirectional. As soon as you remove the @OneToMany end from the Halter2 class you should run into the same problem as I do.
I've written a little test for your sample and have been able to reproduce my problem. The test succeeds if the association is bidirectional but fails if it is unidirectional.

Code:
Halter2 halter = new Halter2();
halter = halterDao.save(halter);
      
Fahrzeug2 fahrzeug = new Fahrzeug2();
fahrzeug.setKennzeichen("BLUP");
fahrzeug.setHalter(halter);
fahrzeug = fahrzeugDao.save(fahrzeug);
//halter.getFahrzeuge().add(fahrzeug);
halter = halterDao.save(halter);
      
halterDao.delete(halter.getId());


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 10, 2007 4:48 am 
Newbie

Joined: Fri Jul 06, 2007 7:05 am
Posts: 5
Hi again,

I've digged a bit deeper into my problem. It seems that the JoinColumn annotation is not necessary in my case. The problem seems to be that if the association is unidirectional it is not possible to declare a cascade behaviour for the not navigable end of the association. I.e. the test succeeds if the Halter2 class simply declares

Code:
@OneToMany (mappedBy = "halter", cascade = CascadeType.ALL)
private Set<Fahrzeug> fahrzeuge = new HashSet<Fahrzeug>();


No getter or setters are necessary for the member 'fahrzeuge'. Just the 'cascade' annotation property has to be set.

- Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 10, 2007 4:16 pm 
Newbie

Joined: Mon Jul 02, 2007 2:12 pm
Posts: 18
Hmmmh,

maybe I still don't understand your problem. If ApprovalRequest hast FK to Image then you cannot delete an reference Image because of the FK. You could update referencing ApprovalRequest to null and then delete the referenced Image. Some database have CASCADE NULLIFY feature.

For the @OneToMany there is optional=true attribute, but your problem in your first post was @ManyToOne.

BTW, if you commit @JoinColumn Hibernate concatenates name of join column from ref. tablen and "_id".

-Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 10, 2007 4:17 pm 
Newbie

Joined: Mon Jul 02, 2007 2:12 pm
Posts: 18
ommit (not commit) :-)


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