2009-06-22 4 views
11

JPA 엔티티에 적어도 하나의 빈 생성자 및 공용 설정자가 있어야한다는 요구 사항이 마음에 들지 않습니다. EntityManager 측면에서이 문제를 이해하는 동안 클래스 invariants가 무효화됩니다.JPA 엔티티에서 빈 생성자 및 설정자

누구나이 (디자인 패턴 또는 관용구 수준)에 대한 해결책이 있습니까?

감사합니다.

이고르

DataNucleus와

답변

1

당신은 당신이 원하지 않는 경우 기본 생성자를 추가 할 필요가 없습니다; 그것은 바이트 코드 강화에 의해 자동으로 추가 될 것입니다. 또한 속성 대신 필드를 유지할 수 있으므로 공개 설정자가 필요하지 않습니다.

--Andy (DataNucleus)

0

예 대신 속성의 필드를 지속하지만, 당신이 일반적으로있어 기본 생성자를 원하는 여부에 (바이트 코드 증강 몇 가지 트릭을하지 않는 한) 당신은하지 않을거야 그것에서 멀리 얻으십시오.

공용 인스턴스 생성자가 필수이므로 클래스를 인스턴스화하려면 jpa 구현을 허용해야합니다.

+0

public이 아닌 protected 일 수도 있습니다. –

17

JPA에서는 기본 생성자가 필요하지만 설정자를 사용할 필요가 없습니다. 어노테이션 배치 위치를 기반으로 특성 액세스 전략 (필드 또는 메소드)을 선택할 수 있습니다.

다음 코드는 직접 필드 액세스를 사용하고 세터없이 엔티티의 일부로서 작동합니다

private String description; 

@Column(name = DESCRIPTION) 
public void setDescription(String description) { 
    this.description = description; 
} 

public String getDescription() { return description; } 
2

은 그냥 생성자를합니다 세터와 방법 액세스 대

@Column(name = DESCRIPTION) 
private String description; 

public String getDescription() { return description; } 

보호되거나 비공개이므로 클래스 상수를 보존합니다!

 
public class Person { 
private String firstName; 
private String lastName; 

public Person(String firstName, String lastName) { 
    setFirstName(firstName); 
    setLastName(lastName); 
} 

// private no-arg constructor for hibernate. 
private Person() { 

} 

public String getFirstName() { 
    return firstName; 
} 
public String getLastName() { 
    return lastName; 
} 

// private setters for hibernate 
private void setFirstName(String nme) { 
    firstName = nme; 
} 
private void setLastName(String nme) { 
    lastName = nme; 
} 
} 

자세한 내용은 http://www.javalobby.org/java/forums/m91937279.html을 참조하십시오.

3

OpenJPA는 엔티티를 향상시키는 요소로 인수가없는 인수를 추가 할 수 있습니다.

분명히 알 수 있듯이 요구 사항은 JPA 사양에 위임되어 있습니다. 이전 대답은 인자가없는 인자를 private로 만들 수 있다고하지만, 이것은 스펙을 따르지 않는다는 것입니다 (링크가 Hibernate 특정 페이지를 가리키고있는 것을 볼 수 있습니다). 명세는 엔티티가 public 또는 protected no-arg ctor를 가져야한다고 명시한다.

-Rick

6

사실의 점에서 당신이 인자없는 생성자와 getter와 setter 메소드 모두 있어야합니다. 요구 사항은 spec 섹션 2.1에 나와 있습니다.

인수 없음의 생성자 요구

내 사본에 17 페이지에 있습니다 :

엔티티 클래스는 인수 없음의 생성자가 있어야합니다. 엔티티 클래스에는 다른 생성자도있을 수 있습니다. no-arg 생성자는 public이거나 이 보호되어야합니다.

18 페이지 접근 방법에 대한 요구 사항이있다 :

엔티티의 지속 상태 콩에게 특성 자바 - 대응할 수있다 인스턴스 변수 로 표시 이다. 인스턴스 변수 은 엔티티 인스턴스 자체로 엔티티의 메소드 내에서만 직접 액세스 할 수 있습니다. 인스턴스 엔티티의 클라이언트는 클라이언트에 액세스하면 안됩니다. 상태는 엔터티의 접근자인 메서드 (getter/setter 메서드) 또는 다른 비즈니스 메서드를 통해서만 클라이언트에 사용할 수 있습니다. 인스턴스 변수는 private, protected, 또는 패키지 공개이어야합니다.

필드 대 등록 정보 액세스는 클라이언트 응용 프로그램과 상호 작용하는 방식이 아니라 JPA 공급자가 사용자 엔터티와 상호 작용하는 방식을 나타냅니다. 클라이언트는 항상 get 및 set 메서드를 사용해야합니다.

일부 JPA 공급자는 이러한 요구 사항에 좀 더 관대하며 특정 공급 업체와 함께 생성자를 비공개로 만들 수 있습니다. 응용 프로그램은 이식 가능하지 않을 수 있으므로 나중에 마이그레이션하는 경우 놀라 울 수도 있습니다.

그래서 전적으로 메서드를 생략하지 않는 것이 좋습니다. 이 문제를 해결하기 위해 public-no-arg ctor를 deprecated로 표시했습니다 (JPA 공급자 전용 인 javadoc에 뭔가 넣으십시오). set 메소드에는 불변성을 유지 보수하려는 논리가 포함될 수 있습니다.

이상한 것은 아니지만 우연히 잘못된 ctor가 사용되는 것을 방지해야합니다 (나는 invariants를 설정하는 ctor가 있다고 가정합니다).

+2

두 번째 인용문에서는 사용자 응용 프로그램의 다른 클래스가 엔티티의 필드에 직접 액세스해서는 안된다고 선언했습니다. JPA 공급자에 대한 접근자를 위임하지는 않습니다. 사실, 다음 문장은 "엔티티의 영구 상태는 JavaBeans 스타일 속성 접근 자 ("속성 액세스 ") 또는 인스턴스 변수 ("필드 액세스 ")를 통해 지속성 공급자 런타임에 의해 액세스됩니다." 이것은 필드 액세스를 사용하는 경우 접근자를 필요로하지 않으므로 읽기 전용 변수를 가질 수 있음을 분명히합니다. – Pace