简体   繁体   English

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

[英]JPA annotate composite primary key that is also a one to many foreign key

Been working on this for a couple of days and haven't yet seen an example that matches what I'm trying to do or I'm missing it as I'm a bit new to Hibernate and JPA. 已经花了几天的时间,但还没有看到一个与我想做的事情相匹配的示例,或者因为我对Hibernate和JPA有点陌生而错过了它。 I'm attempting to convert some hibernate code over to JPA and can't seem to get a particular join correct. 我正在尝试将一些休眠代码转换为JPA,但似乎无法正确实现特定的连接。

Here is my table structure: 这是我的表结构:

Table AppUser 表AppUser

  • id (PK) id(PK)

Table SecurityQuestion 表安全性问题

  • id (PK) id(PK)

Table AppUserSecurityQuestion 表AppUserSecurityQuestion

  • AppUserId (PK, FK to AppUser.id) AppUserId(PK,FK到AppUser.id)

  • SecurityQuestionId (PK, FK to SecurityQuestion.id) SecurityQuestionId(PK,FK到SecurityQuestion.id)

And here is what I've tried to far with my domains (just relevant property declarations): 这是我尝试使用我的域的内容(只是相关的属性声明):

BaseEntity.java 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 AppUser.java

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

AppUserSecurityQuestion.java AppUserSecurityQuestion.java

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

AppUserSecurityQuestionId.java AppUserSecurityQuestionId.java

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

This was working with hibernate configuration but again I'm attempting to convert it over to JPA. 这与休眠配置一起使用,但是我再次尝试将其转换为JPA。 Here are the relevant pieces of the hbm files: 以下是hbm文件的相关部分:

AppUser.hbm.xml 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 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>

I'm basically just trying to look at the hbm's and convert each piece over to JPA but I'm apparently missing something as I get this exception when I try to access data through the application: 我基本上只是在尝试查看hbm并将每段转换为JPA,但是当我尝试通过应用程序访问数据时出现此异常时,我显然丢失了一些东西:

org.hibernate.exception.SQLGrammarException: could not extract ResultSet ... Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'AppUser_AppUserSecurityQuestion' org.hibernate.exception.SQLGrammarException:无法提取ResultSet ...原因:com.microsoft.sqlserver.jdbc.SQLServerException:无效的对象名称'AppUser_AppUserSecurityQuestion'

Here is the HQL as well: 这也是HQL:

select securityan0_.AppUser_id as AppUser_1_0_0_, securityan0_.securityAnswers_appUser as security2_3_0_, securityan0_.securityAnswers_securityQuestion as security3_3_0_, appusersec1_.appUser as 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 and securityan0_.securityAnswers_securityQuestion=appusersec1_.securityQuestion where securityan0_.AppUser_id=? 选择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如Answer3_2_1_从AppUser_AppUserSecurityQuestion securityan0_内部联接上securityan0_.securityAnswers_appUser = appusersec1_ AppUserSecurityQuestion appusersec1_。 appUser和securityan0_.securityAnswers_securityQuestion = appusersec1_.securityQuestion其中securityan0_.AppUser_id =?

I've obviously got my joins declared incorrectly but I'm not sure what else to try at this point. 我的联接显然声明有误,但目前还不确定还有什么尝试。 Anybody see what I'm doing wrong? 有人看到我在做什么错吗?

Figured it out...At least it appears to be working the way I need it to. 想通了...至少它似乎按照我需要的方式工作。 Here are the changes I needed to make: 这是我需要进行的更改:

AppUser.java 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 AppUserSecurityQuestionId.java

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

Everything else remained as is. 其他一切都保持原样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM