Java JPA Query.getResultsList在具有复合键的表上失败

Java JPA Query.getResultsList在具有复合键的表上失败,java,spring,hibernate,Java,Spring,Hibernate,视窗7 爪哇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); my ApplicationContext.xml <!-- omitted --> &

视窗7 爪哇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);
my ApplicationContext.xml

  <!-- omitted  --> 
  <bean id="compositeKey"  class="com.myProject.models.CompositeKey" />
  <bean id="personDao"     class="com.myProject.models.dao.impl.hibernate.PersonDaoImplHibernate" />
Class
Person.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());
    }

}
@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;
    }

}
@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;
    }

}
Class
persondaoimplote.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());
    }

}
@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;
    }

}
@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;
    }

}
抛下恐惧

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)
线程“main”javax.persistence.PersistenceException:org.hibernate.ErrorClassException:Object[id=CompositeKey[id=0,revision=0]]中的异常不属于指定的子类[com.myProject.models.Person]:鉴别器: 位于org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:149) 位于org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157) 位于org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1515) 位于org.hibernate.query.query.getResultList(query.java:146) 在com.myProject.models.dao.impl.hibernate.PersonDaoImplHibernate.getAll(PersonDaoImplHibernate.java:43) 在com.myProject.models.dao.impl.hibernate.PersonDaoImplHibernate$$FastClassBySpringCGLIB$$D0BD1E6.invoke()上 位于org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 位于org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736) 在org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:157)上 位于org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 位于org.springframework.transaction.interceptor.TransactionSpectSupport.invokeWithinTransaction(TransactionSpectSupport.java:282) 位于org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 在org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:179)上 位于org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671) 在com.myProject.models.dao.impl.hibernate.PersonDaoImplHibernate$$EnhancerBySpringCGLIB$$e6f5d088.getAll()上 TestQueries.testPersonGetAll(TestQueries.java:47) main(testquerys.java:74) 请注意,似乎根本没有任何鉴别器-我是否明确需要设置一个,如果是,它将是什么? 复合键和
@embedded
@EmbeddedId
上的示例没有提到鉴别器

蒂亚


code_warrior

问题解决了…事实证明这根本不是@Embedded和@EmbeddedId的问题,而是hibernate.hbm2ddl.auto=update在某个时候改变了我的表的结构

我更喜欢手动创建自己的表,然后构建与之匹配的Java类。 从applicationContext.xml中删除hbm2ddl语句并重新创建表就成功了

在此过程中,我了解到javax.persistence.类型化查询将确保getResultsList()返回正确的类对象列表。我已经适当地更新了代码

感谢大家,


code_warrior

能否尝试将类CompositeKey中“id”字段(类变量)的名称更改为其他名称