【问题标题】:JPA annotate composite primary key that is also a one to many foreign keyJPA 注释复合主键,它也是一对多外键
【发布时间】:2014-10-14 17:03:48
【问题描述】:

已经为此工作了几天,但还没有看到与我正在尝试做的事情相匹配的示例,或者我错过了它,因为我对 Hibernate 和 JPA 有点陌生。我正在尝试将一些休眠代码转换为 JPA,但似乎无法正确获取特定的连接。

这是我的表结构:

表格应用用户

  • id (PK)

表安全问题

  • id (PK)

Table AppUserSecurityQuestion

  • AppUserId(PK、FK 到 AppUser.id)

  • SecurityQuestionId(PK、FK 到 SecurityQuestion.id)

这是我在域中尝试过的内容(只是相关的属性声明):

BaseEntity.java

@MappedSuperclass
public abstract class BaseEntity implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id", updatable=false, nullable=false)
    private Integer id;
    ...
}

AppUser.java

@Entity
@Table(name="AppUser")
public class AppUser extends BaseEntity {
    @OneToMany(fetch=FetchType.EAGER)
    @MapKeyJoinColumn(name="AppUserId")
    private Set<AppUserSecurityQuestion> securityAnswers;
    ...
}

AppUserSecurityQuestion.java

@Entity
@Table(name="AppUserSecurityQuestion")
public class AppUserSecurityQuestion implements java.io.Serializable {
    @EmbeddedId
    private AppUserSecurityQuestionId id;
    ...
}

AppUserSecurityQuestionId.java

@Embeddable
public class AppUserSecurityQuestionId implements java.io.Serializable {
    private AppUser appUser;
    private SecurityQuestion securityQuestion;
    ...
}

这与休眠配置一起使用,但我再次尝试将其转换为 JPA。以下是 hbm 文件的相关部分:

AppUser.hbm.xml

<hibernate-mapping default-access="field">
    <class catalog="WEBR" name="testapp.domain.AppUser" schema="dbo" table="AppUser">
        <id name="appUserId" type="java.lang.Integer">
            <column name="AppUserId" />
            <generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
                <param name="sequence_name">AppUserSeq</param>
            </generator>
        </id>
        ...
        <set name="securityAnswers" table="AppUserSecurityQuestion" inverse="true" lazy="false">
            <key column="AppUserId" not-null="true" />
            <one-to-many class="testapp.domain.AppUserSecurityQuestion" />
        </set>


    </class>
</hibernate-mapping>

AppUserSecurityQuestion.hbm.xml

<hibernate-mapping>
    <class name="testapp.domain.AppUserSecurityQuestion" table="AppUserSecurityQuestion" schema="dbo" catalog="TEST">
        <composite-id name="id" class="testapp.domain.AppUserSecurityQuestionId">
            <key-many-to-one name="appUser" class="testapp.domain.AppUser">
                <column name="id"/>
            </key-many-to-one>
            <key-many-to-one name="securityQuestion" class="testapp.domain.SecurityQuestion">
                <column name="SecurityQuestionId" />
            </key-many-to-one>
        </composite-id>
        <property name="answer" type="java.lang.String">
            <column name="Answer" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

我基本上只是想查看 hbm 并将每个部分转换为 JPA,但是当我尝试通过应用程序访问数据时出现此异常时,我显然遗漏了一些东西:

org.hibernate.exception.SQLGrammarException: 无法提取 ResultSet ... 原因: com.microsoft.sqlserver.jdbc.SQLServerException:对象名称无效 'AppUser_AppUserSecurityQuestion'

这也是 HQL:

选择 securityan0_.AppUser_id 作为 AppUser_1_0_0_, securityan0_.securityAnswers_appUser 作为 security2_3_0_, securityan0_.securityAnswers_securityQuestion 作为 security3_3_0_, appusersec1_.appUser 作为 appUser1_2_1_, appusersec1_.securityQuestion 作为 security2_2_1_, appusersec1_.Answer as Answer3_2_1_ from AppUser_AppUserSecurityQuestion securityan0_ 内连接 AppUserSecurityQuestion appusersec1_ on securityan0_.securityAnswers_appUser=appusersec1_.appUser 和 securityan0_.securityAnswers_securityQuestion=appusersec1_.securityQuestion securityan0_.AppUser_id=?

显然我的连接声明不正确,但我不确定此时还可以尝试什么。有人看到我做错了吗?

【问题讨论】:

    标签: java hibernate jpa composite-primary-key


    【解决方案1】:

    想通了...至少它似乎按照我需要的方式工作。以下是我需要进行的更改:

    AppUser.java

    @Entity
    @Table(name="AppUser")
    public class AppUser extends BaseEntity {
        @OneToMany(mappedBy="id.appUser", fetch=FetchType.EAGER)
        @MapKeyJoinColumn(name="id")
        private Set<AppUserSecurityQuestion> securityAnswers;
        ...
    }
    

    AppUserSecurityQuestionId.java

    @Embeddable
    public class AppUserSecurityQuestionId implements java.io.Serializable {
        @ManyToOne
        @JoinColumn(name="AppUserId")
        private AppUser appUser;
        @ManyToOne
        @JoinColumn(name="SecurityQuestionId")
        private SecurityQuestion securityQuestion;
        ...
    }
    

    其他一切都保持原样。

    【讨论】:

      猜你喜欢
      • 2016-09-18
      • 2022-11-21
      • 1970-01-01
      • 2015-02-03
      • 2017-08-06
      • 1970-01-01
      • 1970-01-01
      • 2012-07-15
      • 1970-01-01
      相关资源
      最近更新 更多