【问题标题】:IllegalArgumentException: expecting IdClass mappingIllegalArgumentException:期待 IdClass 映射
【发布时间】:2012-10-07 12:16:16
【问题描述】:

在部署我的应用程序期间,我发生了该异常。我的应用程序中有很多课程,我不知道我必须在哪里放置@IdClass 以及这个异常到底意味着什么。 我正在使用 Hibernate 4.1 和 JBoss AS 7.1

12:10:23,761 INFO  [org.hibernate.engine.jdbc.internal.LobCreatorBuilder] (MSC service thread 1-5) HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
12:10:24,075 ERROR [org.hibernate.tool.hbm2ddl.SchemaExport] (MSC service thread 1-5) HHH000389: Unsuccessful: drop sequence hibernate_sequence
12:10:24,076 ERROR [org.hibernate.tool.hbm2ddl.SchemaExport] (MSC service thread 1-5) ERROR: sequence "hibernate_sequence" does not exist
12:10:24,281 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-5) MSC00001: Failed to start service jboss.persistenceunit."kladr.ear/kladr-ejb-1.0-SNAPSHOT.jar#primary": org.jboss.msc.service.StartException in service jboss.persistenceunit."kladr.ear/kladr-ejb-1.0-SNAPSHOT.jar#primary": Failed to start service
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1767) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_35]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_35]
    at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_35]
Caused by: java.lang.IllegalArgumentException: expecting IdClass mapping
    at org.hibernate.ejb.metamodel.AttributeFactory$3.resolveMember(AttributeFactory.java:878)
    at org.hibernate.ejb.metamodel.AttributeFactory$4.resolveMember(AttributeFactory.java:915)
    at org.hibernate.ejb.metamodel.AttributeFactory.determineAttributeMetadata(AttributeFactory.java:423)
    at org.hibernate.ejb.metamodel.AttributeFactory.buildAttribute(AttributeFactory.java:91)
    at org.hibernate.ejb.metamodel.MetadataContext.wrapUp(MetadataContext.java:214)
    at org.hibernate.ejb.metamodel.MetamodelImpl.buildMetamodel(MetamodelImpl.java:64)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:91)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:889)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:162)
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.start(PersistenceUnitServiceImpl.java:85)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
    ... 3 more

【问题讨论】:

    标签: java hibernate jboss7.x


    【解决方案1】:

    @IdClass注解用于定义包含id的Class。即,这通常用于定义复合键的情况。即多个属性的关键组合。 如果是这样,那么我们就是这样做的。看看下面的例子.. 我们将一个类定义为IdClass 并使用@Id 来定义各种Ids for thisIdClass`。

    例子:

    @Entity
    @IdClass(AssignedRoleId.class)
    public class AssignedRole
    {
      @Id
      @ManyToOne
      private User userId;
    
      @Id
      @ManyToOne  
      private Role roleId;
    
      private Date dateAssigned;
    }
    

    希望这会有所帮助。

    【讨论】:

    • 如果同时使用@EmbeddedId@Id 可能会导致问题
    【解决方案2】:

    进一步阐述@Mukul 正确答案@IdClass 应具有以下属性:

    1. 它应该实现 Serializable
    2. 它应该有一个接受 id 的构造函数(即与 @Id 关联的字段)
    3. 它应该覆盖equalshashCode

    将这个类作为实体的静态内部类有时很有用,这里有一个例子:

    @Entity 
    @IdClass(AssignedRoleId.class)
    public class AssignedRole
    { 
        @Id
        @ManyToOne
        private User userId;
    
        @Id
        @ManyToOne
        private Role roleId;
    
        private Date dateAssigned;
    
        public static class AssignedRoleId implements Serializable {
    
            private User userId;
            private Role roleId;
    
            public AssignedRoleId() {}
    
            public AssignedRoleId(User userId, Role roleId) {
                this.userId = userId;
                this.roleId = roleId;
            }
    
            @Override
            public boolean equals(Object o) {
    
                if (o == this) {
                    return true;
                }
                if (!(o instanceof AssignedRole)) {
                    return false;
                }
                AssignedRole assignedRole = (AssignedRole) o;
                return Objects.equals(userId, assignedRole.getUserId()) &&
                       Objects.equals(roleId, assignedRole.getRoleId());
            }
    
            @Override
            public int hashCode() {
                return Objects.hash(userId, roleId);
            }
       }
    }
    

    【讨论】:

    • 在我的情况下,我尝试了与您相同的方式,但在 AssignedRoleId.class 中显示了红色标记
    • @ashwinkarki 不确定为什么会这样。它是一个内部类,因此将在同一个包中。您能否详细说明为什么会有红色标记。建议删除所有注释并设置一个基本的内部类。
    • 如果 ID 是 string 和 int 而不是 beans,这是否也适用?
    • @user666 我认为它应该适用于所有需要复合键的类。
    • 就我而言,我创建了一个包含两个字符串和 int 变量的 bean
    【解决方案3】:

    只能覆盖equals和hashcode,问题就解决了,还需要实现java.io.Serializable

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题。原来我没有正确使用 Hibernate(没有 sh!t Sherlock)。我的配置文件 hibernate.cfg.xml 没有包含我的实体 Java 类...我只将 hibernate.cfg.xml 文件用于休眠配置,并且只将 javax.persistence 注释用于我的实体类。

      我刚刚在我的配置文件底部添加了缺少的实体/类(总共 4 个类)并运行了我的测试代码,一切正常?。

      hibernate.cfg.xml

      <?xml version='1.0' encoding='utf-8'?>
      <!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD//EN"
          "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
      <hibernate-configuration>
        <session-factory>
          <property name="connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
          <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
          <property name="connection.username">foo</property>
          <property name="connection.password">bar</property>
          <mapping class="test.entities.MixEntity"/>
          <mapping class="test.entities.ZutatEntity"/>
          <mapping class="test.entities.RezeptEntity"/>
          <mapping class="test.entities.MixEntityPK"/>
        </session-factory>
      </hibernate-configuration>
      

      【讨论】:

        【解决方案5】:

        当我从另一个实体扩展并且还使用@EmbeddedId 时,我遇到了这个错误。它从父实体获取@Id。因此,在同一个实体层次结构中拥有 @Id 和 @EmbeddedId 对我来说是这样的。在我的情况下,错误消息有点误导。我通过不从父级扩展摆脱了错误。

        这不适用于您的情况,因为您没有扩展,但我正在写这个答案是为了让人们因与错误消息中提到的问题不同的问题而收到此错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-01
          • 2019-12-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-13
          相关资源
          最近更新 更多