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;
// ...
}