JPA Query.getResultsList在带有组合键的表上失败

时间:2018-07-16 00:01:29

标签: java spring hibernate

Windows 7 Java 8 春天4 休眠5 MySQL 5

我有一个用复合主键定义的MySql表“ person”

CREATE TABLE person (
  id BIGINT(12) UNSIGNED NOT NULL,
  revision BIGINT(12) UNSIGNED NOT NULL,
  // omitted
  PRIMARY KEY ( id, revision);

我的ApplicationContext.xml

  <!-- omitted  --> 
  <bean id="compositeKey"  class="com.myProject.models.CompositeKey" />
  <bean id="personDao"     class="com.myProject.models.dao.impl.hibernate.PersonDaoImplHibernate" />

CompositeKey.java

@Embeddable
public class CompositeKey implements java.io.Serializable
{
    @GeneratedValue
    @Column( name="id", nullable=false)
    private Long id;

    @Column( name="revision", nullable=false)
    private Long revision;

    //constructors
    public CompositeKey() {
    //  this.id = id;    commented out due to being a generated value on the sql side
        this.revision = 0;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((revision == null) ? 0 : revision.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if ( !( obj instanceof CompositeKey)) return false;
        CompositeKey that = ( CompositeKey) obj;
        return Objects.equals(getId(), that.getId()) && Objects.equals(getRevision(), that.getRevision());
    }

}

Person.java

@Entity
@Table( name="person")
public class Person implements java.io.Serializable
{
    @EmbeddedId
    private CompositeKey compositeKey;

    // omitted

    //constructors
    public Person() {}

    // getters and setters omitted

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((compositeKey == null) ? 0 : compositeKey.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (address == null) {
            if (other.address != null)
                return false;
        } else if (!address.equals(other.address))
            return false;
        if (birthDate == null) {
            if (other.birthDate != null)
                return false;
        } else if (!birthDate.equals(other.birthDate))
            return false;
        // omitted
        return true;
    }

}

PersonDaoImplHibernate.java

@Transactional
public class PersonDaoImplHibernate implements PersonDao
{
    @PersistenceContext( unitName="pu2")
    private EntityManager em;  //injected from bean

    public void setEm( EntityManager em) {
        this.em = em;
    }

    @SuppressWarnings("unchecked")
    public List<Person> getAll() {

        List<Person> results = null;

        String sqlcmd = " SELECT p FROM Person p";
        javax.persistence.Query query = em.createQuery( sqlcmd);
        results =  query.getResultList();  // <<<---- fails on this line

        return results;
    }

}

最后,这是我的独立非Webapp测试程序中的这一行:

results =  query.getResultList();

抛出恐惧

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.WrongClassException: Object [id=CompositeKey [id=0, revision=0]] was not of the specified subclass [com.myProject.models.Person] : Discriminator: 
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:149)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1515)
    at org.hibernate.query.Query.getResultList(Query.java:146)
    at com.myProject.models.dao.impl.hibernate.PersonDaoImplHibernate.getAll(PersonDaoImplHibernate.java:43)
    at com.myProject.models.dao.impl.hibernate.PersonDaoImplHibernate$$FastClassBySpringCGLIB$$d0bde1e6.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
    at com.myProject.models.dao.impl.hibernate.PersonDaoImplHibernate$$EnhancerBySpringCGLIB$$e6f5d088.getAll(<generated>)
    at TestQueries.testPersonGetAll(TestQueries.java:47)
    at TestQueries.main(TestQueries.java:74)

请注意,似乎根本没有任何鉴别符-我是否明确需要设置一个鉴别符,如果是的话,它将是什么? 复合键以及@Embeddable@EmbeddedId上的示例未提及区分符。

TIA,

code_warrior

1 个答案:

答案 0 :(得分:0)

问题解决了……原来根本就没有@Embeddable和@EmbeddedId的问题,而是hibernate.hbm2ddl.auto = update有时改变了我的表结构。

我更喜欢手动创建自己的表,然后构建匹配的Java类。 删除重新创建表并从我的applicationContext.xml中删除hbm2ddl语句就可以解决问题。

在我了解javax.persistence。 Typed Query的过程中,将确保getResultsList()返回适当的类对象的列表。我已经适当更新了代码。

感谢所有人

code_warrior