-->
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.  [ 4 posts ] 
Author Message
 Post subject: Polymorphic Association and Table per Class Strategy
PostPosted: Fri Jul 11, 2008 6:53 pm 
Newbie

Joined: Fri Jul 04, 2008 3:33 pm
Posts: 5
Hi!

I hope you could help me with this: In the top of my application class hierarchy I have the SysObject entity, from which all other classes in my app inherit (SysObject defines the id, name, description and some other attributes), and there must be a many-to-many association between SysObject and itself. My question is: which is the recommended way to map this with annotations and if the TABLE_PER_CLASS strategy can be used. I've tried this strategy, creating an entity SysObjectSysObject with a composite primary key and finally get hibernate to generate the table correctly but when I try to insert the INSERT SQL generated by hibernate duplicates the columns.


Hibernate 3.3.0.CR1
Hibernate Annotations 3.4.0.CR1
Hibernate Commons Annotations 3.1.0.CR1
Hibernate EntityManager 3.4.0.CR1



The SQL generated is as follows:
Code:
17:43:29,704 INFO  [STDOUT] Hibernate:
    insert
    into
        SysObjectSysObject
        (date, firstEnd_id, secondEnd_id, firstEnd_Id, secondEnd_Id)
    values
        (?, ?, ?, ?, ?)
But the SysObjectSysObject table is created by hibernate with the date, firstEnd_Id, secondEnd_Id columns as expected, so I get:
Quote:
java.sql.BatchUpdateException: Column 'secondEnd_Id' specified twice


Code:
@Entity
@Inheritance(strategy = TABLE_PER_CLASS)
public abstract class SysObject implements Serializable {

   @Id
   @GeneratedValue(strategy = GenerationType.TABLE)
   protected Long id;

   @Length(min = 3, max = 50)
   @NotNull
   protected String name;

   @Length(min = 0, max = 255)
   protected String desc;


   @OneToMany(mappedBy = "firstEnd", fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
   protected Set<SysObjectSysObject> associatedObjsA;


   @OneToMany(mappedBy = "secondEnd", fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
   protected Set<SysObjectSysObject> associatedObjsB;

   // ...
}


Code:
@Entity
public class SysObjectSysObject implements Serializable {

   @EmbeddedId
   private SysObjectSysObjectId pk;

   @ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
   private SysObject firstEnd;

   @ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
   private SysObject secondEnd;

   @Temporal(value = TemporalType.TIMESTAMP)
   @NotNull
   private Date date;


   // ...
}


Code:
@Embeddable
@SuppressWarnings("serial")
public class SysObjectSysObject Id implements Serializable {

   @Column(name = "firstEnd_Id", insertable = false, updatable = false)
   private Long firstEndId;

   @Column(name = "secondEnd_Id", insertable = false, updatable = false)
   private Long secondEndId;

   // ...
}


Last edited by juandbotiva on Mon Jul 14, 2008 10:24 am, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 14, 2008 6:33 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi there,

I am not quite sure where the connection between SysObject and SysObjectSysObject is? Where are the actual subclasses of SysObject and what do you try to achieve with SysObjectSysObject? Also where is the many to many association you are talking about?

Could you maybe refine your example?

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 14, 2008 10:08 am 
Newbie

Joined: Fri Jul 04, 2008 3:33 pm
Posts: 5
Hi!

I'll try to explain myself better, in my application I have different classes (among these I have Project, Document, Task, etc.), and all of them share some properties (id, name, description, creation date and user, etc.), I also need to be able to associate one object from one of these classes with another object from any of the other classes, and this association must have a date. That's why I've created the SysObject entity, which has the shared properties all other entities will inherit. To store the association between any two objects from any class I've created the SysObjectSysObject entity which besides having the two references to the associated SysObjects has a date property and to make it bidirectional I've added two OneToMany associations to SysObject. The number of objects that will be stored is huge so I think the best inheritance strategy is TABLE_PER_CLASS so when I need to retrieve objects from only one class no Joins or Unions will happen. I would like to know if this mapping is possible, and if not, if there is a workaround or a better way to do this. Thanks in advance.

I've corrected the source code in the first post.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 15, 2008 7:08 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

I think in your case I would try to use @IdClass. Annotate your one to many associations with @Id and duplicate the associations in your id class (SysObjectSysObjectId).

Have a look at the online documentation and the tests in the source code. There is a package org.hibernate.test.annotations.idmanytoone containing some tests.

If you don't want to download the source you can have a look at these classes on the Hibernate fisheye instance: http://fisheye.jboss.org/browse/Hibernate/annotations/trunk/src/test/org/hibernate/test/annotations/idmanytoone.

--Hardy


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