2013-05-14 57 views
11

Tôi có hai cấu hình bean Entitymanager. Mỗi chỉ vào một cơ sở dữ liệu riêng biệt với một lược đồ khác (một là Oracle, một khác là một H2 trong bộ nhớ)JPA dữ liệu mùa xuân: Các kho lưu trữ cho nhiều cấu hình cơ sở dữ liệu/Entitymanger

Tôi có thể làm gì để giải quyết sự không rõ ràng của Entitymanager cho mỗi Kho lưu trữ? Ngay bây giờ tôi nhận được lỗi này:

No unique bean of type [javax.persistence.EntityManagerFactory] is defined: 
expected single bean but found 2 

Tôi đoán tôi có thể cung cấp một cách nhanh chóng-sửa chữa đơn giản bằng cách sử dụng một cái gì đó giống như

<jpa:repositories base-package="com.foo.repos.ora" 
entity-manager-factory-ref="entityManagerFactoryA"> 

<jpa:repositories base-package="com.foo.repos.m2" 
entity-manager-factory-ref="entityManagerFactoryB"> 

Nhưng hy vọng có một giải pháp tốt hơn.

EDIT:

tôi cung cấp cho bạn một ý tưởng về kịch bản hiện nay:

mùa xuân-Config: đang có hai EM

<jpa:repositories base-package="com.foo.repos.ora" entity-manager-factory-ref="entityManagerFactory"/> 
<jpa:repositories base-package="com.foo.repos.m2" entity-manager-factory-ref="entityManagerFactory2"/> 
<context:component-scan base-package="com.foo" /> .... 

Tất cả mọi thứ từ đây trên là trong "gói com.foo.repos.ora " Theo mẫu của how to make a custom repository Tôi nhận được hai giao diện 'ARepository', 'ARepositoryCustom' và triển khai 'ARepositoryImpl' của nó như vậy

@Repository 
public interface ARepository extends ARepositoryCustom, JpaRepository<myEntity, BigDecimal>, QueryDslPredicateExecutor { 

} 

public interface ARepositoryCustom { 
    FooBar lookupFooBar() 
} 

public class ARepositoryImpl extends QueryDslRepositorySupport implements ARepositoryCustom { 
    ARepositoryImpl(Class<?> domainClass) { 
     super(domainClass.class) 
    } 

    ARepositoryImpl() { 
     this(myEntity.class) 
    } 

    @Override 
    FooBar lookupFooBar() { 
     JPQLQuery query = .... 
     .... 
     return found 
    } 
} 

dẫn đến thông báo lỗi sau:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aRepositoryImpl': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 2

Đó là tất nhiên đúng, có 2 đậu EM, nhưng kể từ khi tôi bị hạn chế EM # 1 aka 'entityManagerFactory' đóng gói 'com.foo .repos.ora 'chỉ, tôi vẫn không chắc chắn làm thế nào để tham khảo chính xác EM đậu.

Trả lời

13

Không có ma thuật dưới mui xe.

<jpa:repositories base-package="com.foo.repos.ora" entity-manager-factory-ref="entityManagerFactory"/> 

không giúp bạn chút nào với triển khai giao diện tùy chỉnh của bạn. Cách tốt nhất tôi tìm thấy là để xử lý các triển khai tùy chỉnh của bạn như là các bean thông thường. Vì vậy, tôi định nghĩa một bean 'sharedEntitManager' trong cấu hình mùa xuân của tôi như vậy

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     ... 
</bean> 
<bean id="sharedEntityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean"> 
     <property name = "entityManagerFactory" ref="entityManagerFactory"/> 
</bean> 

Sau đó, tôi chỉ đơn giản là tiêm các EntityManager vào đậu thực hiện của tôi

<bean id="aRepositoryImpl" class="comm.foo.repos.ora.ARepositoryImpl"> 
    <property name="entityManager" ref="sharedEntityManager"/> 
</bean> 

Các 'thực thể-manager-nhà máy-ref' phân biệt thuộc tính giữa các nhà máy thực thể khác nhau nhưng chỉ dành cho các kho lưu trữ dữ liệu Spring thẳng (tức là chỉ dành cho các giao diện). Tuy nhiên, nó không tự quan tâm đến bất kỳ triển khai nào của bạn.

Nói tóm lại

1) nếu bạn chỉ dựa vào tiêu chuẩn kho dữ liệu mùa xuân với không thực hiện tùy chỉnh, sử dụng thuộc tính "thực thể-manager-nhà máy-ref" để phân biệt cơ sở dữ liệu.

2a) Ngoài ra, nếu bạn sử dụng bất kỳ triển khai tùy chỉnh nào, hãy đưa EntityManager thích hợp trực tiếp vào lớp triển khai. Wirering được thực hiện dưới sự kiểm soát của cấu hình xml mùa xuân của bạn. Vì một số lý do tôi không thể sử dụng chú thích @Autowire với @Qualifier để tham chiếu EntityManager đúng.EDIT Tôi chỉ biết về @Resource chú thích

@Resource(name = "sharedEntityManagerA") 
EntityManager entityManager 


<bean id="sharedEntityManagerA" name="sharedEntityManagerA" class="org.springframework.orm.jpa.support.SharedEntityManagerBean"> 
     <property name = "entityManagerFactory" ref="entityManagerFactory"/> 
</bean> 

Với điều này trong tầm tay chọn những gì EntityMAnger nên được sử dụng trở nên đơn giản. Không cần hệ thống ống nước tất cả mọi thứ togehther trong bối cảnh của bạn xml.

2b) Để thay thế cho cấu hình xml Spring cho hooking lên thứ của bạn, bạn cũng có thể đi với

@PersistenceContext(unitName = "nameOfPersistenceUnit")

để tiêm EntitymanagerFactory đúng

Trong khi referes 'nameOfPersistenceUnit' để kiên trì của bạn ngồi trong bạn JPA persistence.xml chuẩn

Tuy nhiên 2b) không hoạt động tốt với 'QueryDslRepositorySupport', vì nó mong đợi một cá thể EntityManager. Nhưng tôi thấy rằng 'QueryDslRepositorySupport' không cung cấp hỗ trợ nhiều, vì vậy tôi đã xóa nó.

+0

2b) cũng hoạt động như một nét duyên dáng nếu bạn có hai 'LocalContainerEntityManagerFactoryBean' trong ngữ cảnh ứng dụng của bạn, mỗi cái có 'persistenceUnitName' của riêng chúng. –

Các vấn đề liên quan