2009-11-30 5 views
10

나는 특정 카테고리 즉, 고전적인 다 대일 관계에 속한 제품 오브젝트를 가지고 있습니다.선택없이 최대 절전 모드로 삽입 또는 업데이트

@Entity 
public class Product{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id; 

    String name; 
    Double price; 
    @ManyToOne(fetch = FetchType.LAZY) 
    Category category; 
... 
} 

@Entity 
public class Category implements Identifiable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 
... 
} 

카테고리를 미리 선택하지 않고 제품을 삽입하고 업데이트하려고합니다. 이처럼 :

Product product = dao.get(productId); 
Category category = dao.get(categoryId); 
product.setCategory(category); 
dao.update(product); 

또는

Product product = new Product(somename); 
Category category = dao.get(categoryId); 
product.setCategory(category); 
dao.insert(product); 

는 업데이트 및 카테고리 선택하지 않고 삽입 할 수 있습니까? 나는 HQL이나 직접 쿼리를 사용하고 싶지 않다.

답변

10

session.load()이 이와 같은 경우에 특히 존재합니다. 다음 :

Category category = session.load(categoryId); 
product.setCategory(category); 

데이터베이스를 공격하지 않습니다. 그러나 주어진 ID로 사용할 수있는 카테고리가없는 경우 나중의 예외 (플러시, 다소간)에서 예외가 발생합니다. load()를 사용

merge()보다 빠른 어떠한 부작용이 없다 (캐스 케이 딩, 등 ...) 난 그냥 다음 시도했습니다

2

Hibernate는 객체의 상태를 결정하는 안전한 방법을 필요로한다. 그래서 다른 세션의 개체를 혼합 할 수 없도록하기 위해 먼 길을 가고 있습니다. 그래서 시작할 때 범주를로드 한 다음 나중에 사용하는 것은 불가능합니다. 당신이를 구성하는 경우

Product product = new Product(somename); 
product.setCategory(session.merge(category)); 

어떤 DB 왕복 발생하지 않습니다 :

이 솔루션은이 클래스 ehcache처럼 설정, 캐싱 제공자를 시작할 때 카테고리를 넣은 다음이 코드를 사용하는 것입니다 카테고리 인스턴스는 변경할 수 없습니다.

0

:

Category category = new Category(categoryId); 
product.setCategory(category); 

을 그리고 그것은 일, 난 제품 기록을 의미 DB에서 ID가있는 범주 및 카테고리에 대한 올바른 링크가 있습니다.

categoryId 

변경되지 않았습니다.

+1

이 접근법의 문제점은 동일한 식별자를 사용하여 영구 엔터티의 새 인스턴스를 만드는 것입니다. '카테고리'가 ** 현재 ** 세션과 관련되지 않았기 때문에 이번에는 당신에게 도움이되었을 수 있습니다. 만약 그렇다면, Hibernate는 예외를 던질 것이다. 또한 데이터 무결성 측면에서 위험합니다. 'category'에 대한 다 대일에 대한 계단식을 지정하면 위의 코드는 원래 범주를 모든 빈 값으로 덮어 씁니다 (또는 제약 조건 위반 오류로 인해 실패합니다). – ChssPly76

+0

흠, 내가하고있는 감각이있었습니다. 뭔가 더러운 여기. 설명 주셔서 감사합니다. – Vladimir

관련 문제