2011-05-11 3 views
2

Java EE 6 프로젝트에서 현지화 된 동적 (사용자가 작성하고 저장 한) 데이터의 필요성을 해결하기 위해 모든 언어의 문자열을 저장할 수있는 일반적인 지역화 된 문자열 테이블을 만들었습니다. 이것은 ~ 15 개의 여분의 테이블에 물건 이름 만 포함시켜야하는 것을 피하기 위해서입니다. 두 가지 내가 알고 싶은 무엇인가JPA의 현지화 가능 문자열

1)이이 좋은 또는 나쁜 생각, 왜 생각합니까? 2) 단점에 나열된 문제에 대한 깨끗한 해결책을 알고 있습니까?

내 경험 :

프로 : JPA와 DB에 모두 쉽게 구성 할 수 있습니다 하나 개의 테이블이 필요, 일반 솔루션입니다. 중복 된 코드는 존재하지 않습니다.

단점 : 내가 찾아 큰 문제는 인해 muiltilingual_string 테이블이 지금 사용하고있는 개체를 알고에, 모두 삭제는 SQL에서 작동하지 않을 것입니다 (하지만 orphanRemoval와 JPA에서 작동). JPA 외부에서 작업 한 경우 "죽은"문자열이 데이터베이스에 남아있을 수 있습니다.

엔티티 :

@Entity 
@Table(schema = "COMPETENCE", name = "multilingual_string") 
public class MultilingualString extends AbstractEntity{ 

    @ElementCollection(fetch=FetchType.EAGER) 
    @MapKey(name = "language") 
    @CollectionTable(schema = "COMPETENCE", name = "multilingual_string_map", 
        joinColumns = @JoinColumn(name = "string_id")) 
    private Map<Language, LocalizedString> map = new HashMap<Language, LocalizedString>(); 

    public MultilingualString() {} 

    public MultilingualString(Language lang, String text) { 
     addText(lang, text); 
    } 

    public void addText(Language lang, String text) { 
     map.put(lang, new LocalizedString(lang, text)); 
    } 

    public String getText(Language lang) { 
     if (map.containsKey(lang)) { 
      return map.get(lang).getText(); 
     } 
     return null; 
    } 

    public LocalizedString getLocalizedString(Language lang){ 
     if(map.get(lang) == null) 
      map.put(lang, new LocalizedString(lang, null)); 
     return map.get(lang); 
    } 

    @Override 
    public MultilingualString clone(){ 
     MultilingualString ms = new MultilingualString(); 
     for(LocalizedString s : map.values()) 
      ms.addText(s.getLanguage(), s.getText()); 
     return ms; 
    } 

    @Override 
    public String toString() { 
     return getId() == null ? "null " + this.getClass().getName() : getId().toString(); 
    } 
} 

@Embeddable 
public class LocalizedString { 

    @JoinColumn(name="lang_id") 
    private Language language; 

    @Column(name="text") 
    private String text; 

    public LocalizedString() { 
    } 

    public LocalizedString(Language language, String text) { 
     this.language = language; 
     this.text = text; 
    } 

    public Language getLanguage() { 
     return language; 
    } 

    public void setLanguage(Language language) { 
     this.language = language; 
    } 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 

} 

클래스

다른 엔티티에서 다음과 같이 사용된다 (AbstractEntity가 @id 및 @version 함유 매핑 수퍼 클래스)

@OneToOne(cascade=CascadeType.ALL, orphanRemoval=true) 
@JoinColumn(name = "summary_stringid") 
private MultilingualString summary; 

테이블 :

MULTILINGUAL_STRING (
    id bigint primary key 
); 

MULTILINGUAL_STRING_MAP (
    string_id bigint FOREIGN KEY REFERENCES MULTILINGUAL_STRING(id), 
    lang_id bigint FOREIGN KEY REFERENCES LANG(id), 
    text varchar(2000 char), 
    PRIMARY KEY(string_id, lang_id) 
); 

다음과 같이 사용됩니다.

COMPETENCE (
    id bigint PRIMARY KEY, 
    name_id bigint FOREIGN KEY REFERENCES MULTILINGUAL_STRING(id) 
); 

답변

1

내가보기에 하나의 질문은 ResourceBundle의 계단식처럼 작동하지 않는 것입니다.

ResourceBundle에서 로케일이 ES_es 인 경우 ES_es에서 현지화 된 버전을 찾고, 찾지 못하면 ES에서 시도하고 그렇지 않은 경우 기본 문자열을 찾습니다 (실패한 경우를 대비하여). #STRING_ID 문자열 표시). .EN 사전, 영국 고유 표현에는 .EN_uk, 미국 고유 표현에는 .EN_us가 있고 EN_uk와 EN_us에는 필요한 키만 넣을 수 있습니다.

시스템에서는이 옵션을 모두 사용하지 않고 현재 로캘을보고 있으므로 각 로캘의 모든 값을 다시 정의해야합니다. 위의 예에서 EN_uk와 EN_us에 대해 각각의 키 값을 입력해야합니다.

+0

(난 당신이 거기에서 코드를했다 생각) 두 가지 언어를 사용하지 마십시오. –

1

이러한 접근 방식 않습니다 않습니다. 그것은 새로운 것이 아닙니다. 이 그것은, 출판 논의하고 여기에 다른 JPA 제공자에 대해 테스트되었습니다 http://hwellmann.blogspot.com/2010/07/jpa-20-mapping-map.html 다른 로케일은 순수한 텍스트를 처리하고 가장 가능성 때문에 과도 같은 느낌을 포함하여, 내 경우에는