JPA注释复合主键,它也是一对多的外键

时间:2014-10-14 17:03:49

标签: java hibernate jpa composite-primary-key

已经在这方面工作了几天,还没有看到一个与我尝试做的相符的例子,或者我错过了它,因为我有点新鲜Hibernate和JPA。我试图将一些hibernate代码转换为JPA,并且似乎无法使特定连接正确。

这是我的表结构:

  

表AppUser

     
      
  • id(PK)
  •   
     

表安全问题

     
      
  • id(PK)
  •   
     

表AppUserSecurityQuestion

     
      
  • AppUserId(PK,FK to AppUser.id)

  •   
  • SecurityQuestionId(PK,FK to 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;
    ...
}

这是在使用hibernate配置,但我又试图将其转换为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:无效的对象名称   &#39; AppUser_AppUserSecurityQuestion&#39;

这也是HQL:

  

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

我显然已经错误地宣布了我的联接,但我不确定此时还有什么可以尝试。有谁看到我做错了什么?

1 个答案:

答案 0 :(得分: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;
    ...
}

其他一切都保持不变。