2014-12-12 3 views
0

Java EAR에 두 개의 엔티티가 있습니다 : 사용자 및 비밀번호. 물론 데이터베이스에는 사용자 및 암호와 관련된 테이블이 있습니다. passwords 테이블은 사용자의 ID를 외래 키로 포함합니다. 그래서 내 질문에 순수하게 주석을 사용하여 사용자 테이블에서 사용자가 만들어 질 때 암호 테이블에서 암호 항목을 끌어 오려면 어떻게해야합니까? 나는 잃어 버렸다.다른 엔티티에서 엔티티 참조하기

비즈니스 로직을 사용하여 사용자의 관련 비밀번호 엔티티에 액세스하고 싶지 않으므로 컨테이너를 사용해야합니다.

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 
} 

답변

0

간단한 답변으로 충분합니다. 적절한 주석이 있었지만 몇 가지 추가 작업이 필요했습니다. 아래 두 엔티티에 대한 관련 코드가 있습니다.

@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 오류가 발생했습니다.

+2

그리고 1-1 양방향 관계에 대해 "mappedBy"가 누락되었습니다. –

+0

mappedBy 주석이 두 엔티티 또는 기본 엔티티 (이 경우 User) 모두로 이동합니까? 아니면 완전히 기지에서 벗어나나요? Lol –

+0

@ neil-stockton 그래, 나는 그것을 놓쳤다. 지금 편집 중입니다. –

0

엔티티 클래스는 데이터와 관계를 설정합니다. 비즈니스 로직의 특정 인스턴스에서 데이터를 검색합니다. 사용자 및 암호 등록 정보에서 @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 
} 

그러면 사용자 인스턴스를 검색하고 관계 필드로 이동하여 관계를 탐색 할 수 있습니다. 따라서 비즈니스 로직은 다음과 같이 보일 수 있습니다.

@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이 지적한대로 mappedBy를 사용하여 관계의 소유자를 설정해야합니다.

+0

나는 그것을 얻는다 - 나는 사용자가 발견 된 후에 암호를 얻기 위해 약간의 논리를 사용할 수있다. 오히려 그것을 피하고 컨테이너가 데이터베이스에서 사용자의 암호를 가져 오도록 관리하게하십시오. 이 논리를 구현하려면 엔티티 외부로 나가서 JPA 컨트롤러를 사용해야합니다. 컨테이너가 자동으로 사용자 비밀번호 필드를 채울 수 있습니까? 패스워드 엔티티는 패스워드 스트링을 포함하고 있지만 간단한 예를 위해 생략했다. 생략 된 사용자 이름은 문자열입니다. 표시되는 long 값은 테이블의 각 행에 대한 식별자입니다. –

+0

컨테이너는 찾기 작업이나 쿼리에서 사용자 인스턴스를 검색 한 후 자동으로 User.password를 채 웁니다.이 경우 다른 엔터티입니다. 엔티티를 찾고 관계 필드를 탐색해야합니다. 예를 들어, 주어진 사용자 ID에 대한 암호 엔티티를 검색하기 위해 JPQL 조회를 작성할 수 있습니다. 하지만 엔티티 클래스에 모든 로직을 추가하는 것이 좋습니다. JPA 작동 방식이 아닙니다. 엔티티를 사용하여 데이터를 모델링 한 다음 EntityManager 작업을 사용하여 엔티티를 관리합니다. –

+0

글을 올리던 때가 아니 었습니다. 그러나 지금은 주어진 대답으로되어 있습니다. 엔티티에 어떤 논리도 원하지 않습니다. 엔티티가 자신의 관계를 처리하여 세션 콩의 비즈니스 로직에 집중할 수 있기를 바랍니다. –

관련 문제