-->
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: Problem when saving with Inheritance annotation
PostPosted: Tue Dec 01, 2015 8:58 am 
Newbie

Joined: Tue Dec 01, 2015 8:53 am
Posts: 3
Hi,
I'm using @Inheritance annotation with InheritanceType.JOINED startegy and I have a strange bug when I try to insert an object.
I use this simple mapping :
Code:
@Entity
@Table(name = "tb_foo")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Foo {
    @Id
    @Column(name = "ID_ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;
}

Code:
@Entity
@Table(name = "tb_bar")
@PrimaryKeyJoinColumn(name = "Foo_ID")
public class Bar extends Foo {
    @Column(name = "val")
    private String val;
}


When I just perform a save :
Code:
Session session = new Configuration().configure(resource).buildSessionFactory().openSession();
        session.beginTransaction();
        Bar bar = new Bar();
        session.save(bar);
        session.getTransaction().commit();



I have the error :
Code:
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [fr.viveris.vizada.box.tests.Bar]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:63)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2346)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2853)
        at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
        at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:320)
        at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
        at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
        at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
        at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
        at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:713)
        at org.hibernate.impl.SessionImpl.save(SessionImpl.java:701)
        at org.hibernate.impl.SessionImpl.save(SessionImpl.java:697)
        at fr.viveris.vizada.box.tests.Bar.main(Bar.java:25)
Caused by: org.postgresql.util.PSQLException: The column name Foo_ID was not found in this ResultSet.
        at org.postgresql.jdbc2.AbstractJdbc2ResultSet.findColumn(AbstractJdbc2ResultSet.java:2728)
        at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getLong(AbstractJdbc2ResultSet.java:2594)
        at org.hibernate.id.IdentifierGeneratorHelper.get(IdentifierGeneratorHelper.java:145)
        at org.hibernate.id.IdentifierGeneratorHelper.getGeneratedIdentity(IdentifierGeneratorHelper.java:88)
        at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:97)
        at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:56)
        ... 16 more


I suspect that hibernate first insert data in table tb_foo and then search the generated id to do the insertion in tb_bar. But it seems that hibernat trying to get the ID using the field 'Foo_ID' instead of using the field 'ID_ID'.
Maybe I'm doing something wrong ?

I use Postgresql as database with these tables :
Code:
create table IF NOT EXISTS tb_foo (
   ID_ID bigserial not null primary key,
   name varchar
);

create table IF NOT EXISTS tb_bar (
   Foo_ID bigint not null primary key,
   val varchar,
   FOREIGN KEY (Foo_ID) REFERENCES tb_foo (ID_ID)
);


I use hibernate in version 3.6


Last edited by kserin1 on Tue Dec 01, 2015 10:45 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Problem when saving with Inheritance annotation
PostPosted: Tue Dec 01, 2015 9:41 am 
Regular
Regular

Joined: Mon Oct 19, 2015 7:49 am
Posts: 61
Location: ChengDu China
Hi kserin1

The id field in the super class declared as long, please change it to be Long which can be null, In JPA/Hibernate, null id means the object is transient(Haven't be inserted into in database)

(1) For JPA annotation(Your style), don't declare the id type to primitive.
(2) For classic hibernate hbm.xml mapping, primitive id is not suggested too, but if you must used it, please do it like this
<id ....type="long"... unsaved-value="0"/>


Top
 Profile  
 
 Post subject: Re: Problem when saving with Inheritance annotation
PostPosted: Tue Dec 01, 2015 10:44 am 
Newbie

Joined: Tue Dec 01, 2015 8:53 am
Posts: 3
I just replace it by 'Long' instead of 'long' but the problem still remain.
(I modified the code posted before)


Top
 Profile  
 
 Post subject: Re: Problem when saving with Inheritance annotation
PostPosted: Tue Dec 01, 2015 10:55 am 
Regular
Regular

Joined: Mon Oct 19, 2015 7:49 am
Posts: 61
Location: ChengDu China
Try to use the same primary key column name.


Top
 Profile  
 
 Post subject: Re: Problem when saving with Inheritance annotation
PostPosted: Wed Dec 02, 2015 5:07 am 
Newbie

Joined: Tue Dec 01, 2015 8:53 am
Posts: 3
I think the problem come from the JoinedSubclassEntityPersister class. It uses the 'tableKeyColumns' field to determine the id to get in the result set. In my cas the field contains '[Foo_ID, ID_ID]' which is not the correct order (maybe the 'naturalOrderTableKeyColumns' field must be used instead). I think it's a real bug.

So, of course, if I use the same name for the PrimaryKeyJoinColumn, it will work because hibernate will not confuse the two columns.

The solution I use is to change the ID generation strategy. In postgreSQL, a sequence is automatically created for Serial types. So I change my code to this :
Code:
@Entity
@Table(name = "tb_foo")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Foo {
    @Id
    @Column(name = "ID_ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "foo_seq")
    @SequenceGenerator(name = "foo_seq", sequenceName = "tb_foo_id_id_seq", allocationSize = 1)
    private Long id;

    @Column(name = "name")
    private String name;
}

Thus, hibernate will generate the id before perform the insertions (in tb_foo and tb_bar), but it doesn't need to check the result set of the first insertion (in tb_foo) to do the second because the ID is already known.


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.