-->
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 with a one-to-many relation using annotation
PostPosted: Thu Jun 14, 2007 10:06 am 
Beginner
Beginner

Joined: Thu Aug 31, 2006 7:41 am
Posts: 24
Hi,

recently I changed from using .hbm.xml files to using annotations and now a particular association is giving me headaches when comitting transactions that store new objects in the database.

In particular this is a bidirectional One-To-Many association with the Many-Side being the owner. I'm trying to store the new objects of both classes within the same transactions and always get an error about violating the foreign key constraint of the many-table, because the object in the one-table doesn't exist.

The 2 tables involved are media and logentry and it seems that for some reason hibernate wants to persist logentry before media. The association is 1 media has multiple logentries. I already checked that when I add a new logentry to media I also set the media attribute of that logentry properly. And the Many-To-One annotation in logentry uses a CascadeType.ALL.

The 2 classes annotations are this:
Code:
@Entity
public class Media implements java.io.Serializable
{
    @Id @GeneratedValue
    private int id;
   
    @OneToMany( mappedBy="media" ) 
    private Set<LogEntry> logEntries = new HashSet<LogEntry>(0);
}

@Entity
@Table (name="log")
public class LogEntry
{
    @Id @GeneratedValue
    private int id;
   
    @ManyToOne( cascade = {CascadeType.ALL} )
    private Media media;
}


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 15, 2007 12:49 am 
Senior
Senior

Joined: Sat Aug 19, 2006 6:31 pm
Posts: 139
Usually you'd put the cascade on the one side of the one-many.

And then you'd do

logEntry.setMedia(media);
media.getLogEntries().add(logEntry);

session.save(media);

So you save the one side.

_________________
Don't forget to rate the reply if it helps..:)

Budyanto


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 15, 2007 5:15 pm 
Beginner
Beginner

Joined: Thu Aug 31, 2006 7:41 am
Posts: 24
himawan wrote:
Usually you'd put the cascade on the one side of the one-many.

And then you'd do

logEntry.setMedia(media);
media.getLogEntries().add(logEntry);

session.save(media);

So you save the one side.


I can't test this at the moment, but IIRC I can't used mappedBy in the ManyToOne annotation. Apart from that this is what can be read in the reference documentation. I'll try again the "other way around" on monday.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 19, 2007 6:32 am 
Beginner
Beginner

Joined: Thu Aug 31, 2006 7:41 am
Posts: 24
himawan wrote:
Usually you'd put the cascade on the one side of the one-many.

And then you'd do

logEntry.setMedia(media);
media.getLogEntries().add(logEntry);

session.save(media);

So you save the one side.


I just tried and while I can put the cascade on the one-side I can't use mappedBy on the many-side, i.e.

@ManyToOne( mappedBy="logentries" )

is an error. Also using the above hibernate expects to see a join-table which I also don't want.

The hibernate annotation reference documentation also doesn't show this for bidirectional many-to-one associations. I has the same as I originally posted with the Many-Side as the owner.

I guess I should post this in the annotation forum...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 19, 2007 8:03 am 
Regular
Regular

Joined: Wed May 05, 2004 8:01 am
Posts: 53
Annotation documentation states:

To map a bidirectional one to many, with the one-to-many side as the owning side, you have to remove the mappedBy element and set the many to one @JoinColumn as insertable and updatable to false. This solution is obviously not optimized and will produce some additional UPDATE statements.

@Entity
public class Troop {
@OneToMany
@JoinColumn(name="troop_fk") //we need to duplicate the physical information
public Set<Soldier> getSoldiers() {
...
}

@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk", insertable=false, updatable=false)
public Troop getTroop() {
...
}

Please rate if that helped


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.