views:

88

answers:

2

I would like to implement inheritance in Hibernate.

I created ObjectClass object:

@Entity
@Table(name = "object")
@Inheritance(strategy = InheritanceType.JOINED)
public class ObjectClass {
    private id;

}

and CodeTable object that inhertance Object class:

@Entity
@ForeignKey(name = "id")
@Table(name = "code_table")
public class CodeTable extends  ObjectClass{
    private String description;
}

in the database

object table is:

CREATE TABLE `object` (
  `id` bigint(11) NOT NULL auto_increment,
    PRIMARY KEY  (`id`),
 )

code_table table is:

-

CREATE TABLE `code_table` (
  `id` bigint(11) NOT NULL auto_increment,
  `description` varchar(45) character set latin1 default NULL,
   PRIMARY KEY  (`id`),
   KEY `FK_object` (`id`),
  CONSTRAINT `FK_object` FOREIGN KEY (`id`) REFERENCES `object` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
 ) 

I wrote the following code to retreive data from codeTable:

 @SuppressWarnings( "unchecked" )
    @Transactional( readOnly = true, propagation = Propagation.REQUIRED )
    public Collection<CodeTable> findAll() {
        Session session = getSessionFactory().getCurrentSession();

        return 
            session.createCriteria( persistentClass 
                    ).setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY
                            ).list();
    }

I gets empty list although there is one record in codetable table.

When I write the following SQL in my database:

SELECT * FROM `code_table`

I get: id= 1, description = company.

What went wrong in my Hibernate definition? How can I retrieve the object?

EDITED: My hibernate.cfg.xml file looks like this:

<hibernate-configuration>
    <session-factory>
           <mapping class="com.mycompany.model.CodeTable" />
           <mapping class="com.mycompany.model.ObjectClass" />
        </session-factory>  
</hibernate-configuration>
+1  A: 

How does your mapping looks like ?

Have you read this section in the Hibernate doc ? Inheritance mapping in Hibernate

As you can read in the link I provided above, your mapping is not correct. You have to let Hibernate know that the code_table class inherits from the object class, and you 'll have to let Hibernate know how this link exists in the database.

Frederik Gheysels
I edited my question with the mapping file
Rivki
+1 for pointing out incorrect mapping.
Tushar Tarkas
How should I change my mapping in hibernate.cfg.xml?
Rivki
Rivki, please read the document that I refer to. All the information that you're looking for, is in there. There are some design decisions that you'll have to make.
Frederik Gheysels
She uses annotation! why does she need to map it in a different file?See them above the object declaration..
Odelya
Hi Frederik, The offered way will works with an old version of Heibernate,Heibernate 3 dones't need mapping for the tables, it uses Heibernate annotations instead.my questions is how to define Heibernate annotations for a sub class??10X
Rivki
+2  A: 

Your mappings and table structure are (roughly) correct for a JOINED inheritance strategy and I cannot reproduce your problem.

I use the following mappings (which are basically the one you provided):

@Entity
@Table(name = "object")
@Inheritance(strategy = InheritanceType.JOINED)
public class ObjectClass {
    @Id @GeneratedValue 
    private Long id;

    public ObjectClass() { }

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
}

And

@Entity
@ForeignKey(name = "id")
@Table(name = "code_table")
public class CodeTable extends  ObjectClass{
    private String description;

    public CodeTable() { }

    public String getDescription() { return description; }
    public void setDescription(String description) { 
        this.description = description; 
    }
    @Override
    public String toString() {
    return "CodeTable [getDescription()=" + getDescription() + ", getId()="
            + getId() + "]";
    }
}

The following tables:

create table code_table (
    description varchar(255),
    id bigint not null,
    primary key (id)
)

create table object (
    id bigint not null,
    primary key (id)
)

alter table code_table 
    add constraint id 
    foreign key (id) 
    references object

And the following parent/child records:

insert into object values (1);
insert into code_table(id, description) values (1, 'foo');

And running your criteria query:

session.createCriteria(CodeTable.class)
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
    .list();

Returns:

CodeTable [getDescription()=foo, getId()=1]

Everything works as expected.

References

Pascal Thivent
@Pascal: you wrote "(roughly) correct" what is not correct about her implementation?
Odelya
@Odelya: Things like no Java type for the `id`, no mandatory `Id` annotation (but the inheritance part itself is correct).
Pascal Thivent
Tanks Pascal,My mistake was in the annotation: I defined the “catalog” for certain database and connected to a different one… :(
Rivki
@Rivki: Stuff happens :) Glad it's fixed though.
Pascal Thivent