Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
Hibernate version: 3.1
Mapping documents: Annotations
Debug level Hibernate log excerpt:
I am having problems defining an @EmbeddableSuperclass relationship. In my domain model, I have objects that implement a tree structure, i.e. they each have a parent node and a list of children nodes, all of the same type. I though that I'd extract the common functionality such as the parent and child properties and some utility methods into a superclass.
Code:
@EmbeddableSuperclass(access = AccessType.PROPERTY)
public abstract class DAFEntityNamedTree extends DAFEntityNamed
{
protected List<DAFEntityNamedTree> children = null;
protected DAFEntityNamedTree parent = null;
/**
* @return Returns the children.
*/
@OneToMany
@OrderBy("name")
@JoinColumn(name = "parent")
@Cascade( { org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
public List<DAFEntityNamedTree> getChildren()
{
return children;
}
/**
* @return Returns the parent.
*/
@ManyToOne
@JoinColumn(name = "parent", insertable = false, updatable = false)
public DAFEntityNamedTree getParent()
{
return parent;
}
/**
* @param children The children to set.
*/
public void setChildren(List<DAFEntityNamedTree> children)
{
this.children = children;
}
/**
* @param parent The parent to set.
*/
public void setParent(DAFEntityNamedTree parent)
{
this.parent = parent;
}
}
I also have a superclass used to define a name property:
Code:
@EmbeddableSuperclass(access = AccessType.PROPERTY)
public abstract class DAFEntityNamed extends DAFEntity
{
protected String name = null;
/**
* @return Returns the name.
*/
@NotNull
public String getName()
{
return name;
}
/**
* @param name The name to set.
*/
public void setName(String name)
{
this.name = name;
}
}
and a superclass used to define an id property:
Code:
@EmbeddableSuperclass(access = AccessType.PROPERTY)
public abstract class DAFEntity
{
protected Integer id = null;
/**
* @return Returns the id.
*/
@Id(generate = GeneratorType.IDENTITY)
public Integer getId()
{
return id;
}
/**
* TODO Document this method
*
* @return boolean
*/
@Transient
public boolean isNew()
{
return (this.id ==null);
}
/**
* @param id The id to set.
*/
public void setId(Integer id)
{
this.id = id;
}
}
If I setup my domain object so that it extends the base abstract class DAFEntityNamedTree as it is shown below, I get the following message when trying to run the hbm2ddl tool -
org.hibernate.AnnotationException: Unable to find entity com.compudata.daf.domain.DAFEntityNamedTree.
Code:
@Entity
public class Category extends DAFEntityNamedTree
{
}
If I put the @Entity annotation on the DAFEntityNamedTree, the hbm2ddl tools completes but I end up with a DAFEntityNamedTree table in the database, with the parent column in the Category table referencing the id column of DAFEntityNamedTree via a foreign key. I want the parent column on the Category table to reference itself and for there not to be a DAFEntityNamedTree table in the database at all. What am I doing wrong that's preventing this from happening?
Here's the SQL code that gets created by hbm2ddl when I do have the @Entity annotation on the DAFEntityNamedTree abstract class:
Code:
drop table if exists Category;
drop table if exists DAFEntityNamedTree;
create table Category (id integer not null auto_increment, name varchar(255) not null, parent integer, primary key (id), unique (name, parent)) type=InnoDB;
create table DAFEntityNamedTree (id integer not null auto_increment, name varchar(255) not null, parent integer, primary key (id)) type=InnoDB;
alter table Category add index FK6DD211EDF051E2F (parent), add constraint FK6DD211EDF051E2F foreign key (parent) references DAFEntityNamedTree (id);
alter table DAFEntityNamedTree add index FK8FFD372B219C50A2 (parent), add constraint FK8FFD372B219C50A2 foreign key (parent) references Category (id);