簡體   English   中英

從另一個實體引用一個實體

[英]Referencing an Entity from another Entity

我的Java EAR中有兩個實體:用戶和密碼。 當然,這些在數據庫中具有對應的表:用戶和密碼。 密碼表包含用戶ID作為外鍵。 所以我的問題是,當使用純注解從Users表中創建User時,如何從Passwords表中提取密碼條目? 我很茫然。

我不想使用業務邏輯來訪問用戶的相關密碼實體,因此我需要容器為我完成此任務。

SCCE:

@Entity
@Table(name = "USERS")
public class User{
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "IDENTIFIER", nullable = false)
        private Long identifier;

    @JoinColumn(name = "UserIdentifier")
    @OneToOne
    private Password password;

    // getters, setters, and other User related information such as username
}

@Entity
@Table(name = "PASSWORDS")
public class Password{
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "IDENTIFIER", nullable = false)
        private Long identifier;

    @JoinColumn(name = "USERIDENTIFIER", referencedColumnName = "IDENTIFIER", nullable = false)
    @OneToOne(optional = false, fetch = FetchType.EAGER)
        private User useridentifier;
    //getters, setters, and other password related fields such as the password it's self
}

實體類只是建立數據和關系。 您可以從業務邏輯中的特定實例檢索數據。 您已經在User和Password屬性上使用@OneToOne批注建立了關系。 您缺少的是Password實體的持久字段。

@Entity
@Table(name = "PASSWORDS")
public class Password{
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "IDENTIFIER", nullable = false)
    private Long identifier;

    @JoinColumn(name = "USERIDENTIFIER", referencedColumnName = "IDENTIFIER", nullable = false)
    @OneToOne(mappedBy = "password", optional = false, fetch = FetchType.EAGER)
    private User useridentifier;

    @NotNull
    private String passwordValue;

    // getters/setters go here, since your annotated fields are private 
}

然后,您可以通過檢索User實例並導航到關系字段來遍歷關系。 因此,您的業務邏輯可能看起來像這樣:

@PersistenceContext
EntityManager em;

Long userIdInput = ...;
String passwordInput = ...;

User user = em.find(User.class, userIdInput);
// compare the input password with the stored password
// retrieve the Password instance by navigating to the relationship field
if (passwordInput.equals(user.getPassword().getPasswordValue()) {
    // passwords match
} else {
    // passwords don't match
}

您的用戶名是Long值,這很奇怪。 您可能應該研究如何安全地處理將密碼值存儲在數據庫中,因為不加密地存儲密碼不是一個好習慣。 但這是JPA的要旨。

編輯:關系的所有者需要使用@ neil-stockton指出的mapByBy設置。

原來答案很簡單。 我有正確的注釋,但我需要一些額外的東西。 以下是兩個實體的相關代碼。

@Entity
@Table(name = "USERS")
public class User{
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "IDENTIFIER", nullable = false)
        private Long identifier;

    @JoinColumn(referencedColumnName = "PASSWORDS.USERIDENTIFIER", name="USERS.IDENTIFIER")
    @OneToOne
    private Password password;

    // getters, setters, and other User related information such as username
}

@Entity
@Table(name = "PASSWORDS")
public class Password{
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "IDENTIFIER", nullable = false)
        private Long identifier;

    @JoinColumn(name = "USERIDENTIFIER", referencedColumnName = "IDENTIFIER", nullable = false)
    @OneToOne(optional = false, fetch = FetchType.EAGER)
        private User useridentifier;
    //getters, setters, and other password related fields such as the password it's self
}

因此,對於將來擁有一個實體引用另一個實體的堆棧器,您應該指定JoinColumn批注的名稱和referencedColumnName來獲取要拉入相關實體的容器。 通過這樣做,我能夠從數據庫中提取正確的密碼行。 請注意,用戶實體中的joincolumn批注也必須具有表名,而密碼實體中的同一批注必須不能具有表名。 否則它將無法正常工作-相信我,我嘗試了一下並出現了StackOverflow錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM