Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Postgres identity in single table hierarchy
PostPosted: Tue Aug 25, 2009 7:22 am 
Newbie

Joined: Mon Jun 27, 2005 11:49 am
Posts: 7
Location: Norwich, UK
Hi,

Firstly my environment:

PostgreSQL 8.3
Hibernate-entitymanager 3.4.0.GA <-- installed from Glassfish update tool
Hibernate-distribution 3.3.1.GA <-- installed from Glassfish update tool
Glassfish V2
Mac OS X 10.5.x

I'm having an issue when using a GenerationType of IDENTITY with a single table inheritance hierarchy.

Here's my two entities:

Parent.java
Code:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="generation", discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue("Parent")
public class Parent implements Serializable {
    private static final long serialVersionUID = 1L;
   
    private Long id;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

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

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Parent)) {
            return false;
        }
        Parent other = (Parent) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Parent[id=" + id + "]";
    }

}

Child.java
Code:
@Entity
@DiscriminatorValue("Child")
public class Child extends Parent {
    private String babyName;

    /**
     * @return the babyName
     */
    public String getBabyName() {
        return babyName;
    }

    /**
     * @param babyName the babyName to set
     */
    public void setBabyName(String babyName) {
        this.babyName = babyName;
    }
}


DDL
Code:
create table Parent (
        generation varchar(31) not null,
        id  bigserial not null,
        babyName varchar(255),
        primary key (id)
    );


If I try to insert a new Parent I get an error:

Code:
org.postgresql.util.PSQLException: Bad value for type long : Parent


I turned up the logging to TRACE and this is the output:

Code:
TRACE TransactionSynchronizationManager - Bound value [org.springframework.orm.jpa.EntityManagerHolder@485e0366] for key [com.sun.enterprise.util.EntityManagerFactoryWrapper@a6e312b] to thread [httpSSLWorkerThread-8080-0]
Hibernate: insert into Parent (generation) values ('Parent')
SQL Error: 0, SQLState: 22003
Bad value for type long : Parent
TRACE TransactionInterceptor - Completing transaction for [com.xxx.yyy.service.MoveService.saveHuman] after exception: javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not insert: [com.xxx.yyy.temp.Parent]
TRACE RuleBasedTransactionAttribute - Applying rules to determine whether transaction should rollback on javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not insert: [com.xxx.yyy.temp.Parent]


If I change the discriminator value to be something that parses as a long e.g. 123 the insert succeeds. However Hibernate seems to think this discriminator value is the id. So the following code:

Code:
Parent p = new Parent();
service.saveHuman(p);

add(new Label("p", "p id is" + p.getId()));


Shows the id as 123 rather than the primary key value which is 1.

If I change the generation type to AUTO a single sequence is created and it seems to work ok. However I don't want a single sequence across all my tables.

I also tried the exact same code and switched out the database with MySQL 5.0.51b. This seems to function fine.

So is this a bug in my code, the dialect, hibernate, or the PostgreSQL JDBC driver? Any ideas how I can narrow down the problem? Anyone able to re-produce this issue as I have tried to search and haven't seen this exact problem yet.

Many thanks

Stephen


Top
 Profile  
 
 Post subject: Re: Postgres identity in single table hierarchy
PostPosted: Tue Feb 02, 2010 11:00 pm 
Newbie

Joined: Tue Feb 02, 2010 10:57 pm
Posts: 1
I'm having the exact same issue, with the same configuration. Anyone have any idea?


Top
 Profile  
 
 Post subject: Re: Postgres identity in single table hierarchy
PostPosted: Wed Feb 03, 2010 6:06 am 
Newbie

Joined: Mon Jun 27, 2005 11:49 am
Posts: 7
Location: Norwich, UK
I ended up using sequences on each Entity:

Code:
@Entity
@SequenceGenerator(name = "SEQ_STORE", sequenceName = "bidSequence", allocationSize = 1)
public class Bid {

  ...

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_STORE")
  public Long getBidId() {
      return bidId;
  }
}


Which seems to work fine now.


Top
 Profile  
 
 Post subject: Re: Postgres identity in single table hierarchy
PostPosted: Wed Dec 08, 2010 3:51 am 
Newbie

Joined: Thu Jul 22, 2010 6:47 pm
Posts: 2
I was just experiencing the same problem as you guys. By any chance, was your discriminator column the first column in the table?
Oddly enough, moving that column to the end of the table (dropping and re-adding the column) seems to have fixed the problem for me. Things seem to be working great now, but time will tell if something else weird pops up.

P.S. I had let Hibernate generate the tables for me and it is the one that puts the discriminator column in the first position.


Top
 Profile  
 
 Post subject: Re: Postgres identity in single table hierarchy
PostPosted: Thu Dec 09, 2010 2:08 pm 
Newbie

Joined: Thu Dec 09, 2010 1:52 pm
Posts: 1
Thank you very much for posting jones72. Like you, I used Hibernate to generate my database schema and the discriminator column was in first position.
I've just put it after the id column and everything works well.

Just for information, my error message was :
Code:
Hibernate:
    insert
    into
        Article
        (name, version, AVAILDATE, IDCAT, description, charge, options, ARTICLETYPE)
    values
        (?, ?, ?, ?, ?, ?, ?, 'S')
1291913594229|47|3|statement|insert into Article (name, version, AVAILDATE, IDCAT, description, charge, options, ARTICLETYPE) values ('a service', 0, '2010-12-31 00:00:00.0', 1, 'a service', 2.0, 'no', 'S')
17:53:14,276 WARN  JDBCExceptionReporter(100) - SQL Error: 0, SQLState: 22003
17:53:14,276 ERROR JDBCExceptionReporter(101) - Mauvaise valeur pour le type intá: S


I don't know why the jdbc exception is in french, and why I have an extra character "á" after "int", but this is not a bad copy/past.

Regards,
Bernard


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 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.