2013-03-08 15 views
7

Chúng tôi có một mô hình thực thể mở rộng với hơn 100 lớp thực thể. Tất cả các lớp thực thể là các lớp con của một siêu thực thể đơn. Chế độ bộ nhớ cache dùng chung đã được đặt thành TẤT CẢ.Vùng bộ nhớ cache chuyên dụng cho các lớp con thực thể?

@Entity 
@Inheritance(strategy = InheritanceType.JOINED) 
@Table(name = "entities") 
public abstract class LongIdEntity { 

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

    @Version 
    @Column(name = "OPT_LOCK_VERSION") 
    private Long lockVersion; 

    etc... 

} 

Một ví dụ lớp con:

@Entity 
@Table(name = "cars") 
public class Car extends LongIdEntity { ... } 

Chúng tôi muốn bộ nhớ cache tất cả các đơn vị trong bộ nhớ cache cấp 2. Vấn đề là chỉ có 1 vùng nhớ đệm được tạo cho tất cả các thực thể; có tên là LongIdEntity.

Các chương trình gỡ lỗi Hibernate đã làm tìm tất cả các lớp thực thể, nhưng vẫn gán chúng cùng một vùng. Bởi vì tại SessionFactoryImpl: 339:

String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName(); 

Trong trường hợp của chúng tôi, các cuộc gọi đến model.getRootClass() sẽ luôn mang lại "LongIdEntity".

Tôi cho rằng điều này thực sự sẽ lưu tất cả các thực thể, nhưng không có bất kỳ sự kiểm soát nào về việc trục xuất. Một số lớp học rất thường xuyên và chỉ đọc. Vì vậy, chúng tôi muốn giữ chúng gắn vào bộ nhớ. Một số thường được sử dụng trong một khoảng thời gian nhất định, vv ... Cramming tất cả vào cùng một bộ nhớ cache invalidates tất cả.

Chỉ định khu vực trong chú thích không có hiệu lực. Ví dụ:

@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,region = "cars") 
@Entity 
@Table(name = "cars") 
public class Car extends LongIdEntity { ... } 

Điều lạ là chỉ chia sẻ chế độ bộ nhớ cache ALL nhặt các lớp thực thể. Trong bất kỳ chế độ nào khác, không có thực thể nào - ngay cả khi được chú thích bằng @Cache và/hoặc @Cacheable. Có lẽ đây là một dấu hiệu?

Ai đó có ý tưởng về cách tôi có thể chỉ định các lớp thực thể cụ thể cho các vùng cụ thể?

TIA :-)

persistence.xml là tiểu:

nhà máy
<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
    <persistence-unit name="cars" transaction-type="RESOURCE_LOCAL"> 
    <shared-cache-mode>ALL</shared-cache-mode> 
    </persistence-unit> 
</persistence> 

Phiên họp được thực hiện theo cách cổ điển:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/> 
    <property name="persistenceUnitName" value="optimus"/> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="jpaProperties"> 
     <props> 
     <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop> 
     <prop key="hibernate.cache.use_second_level_cache">true</prop> 
     <prop key="hibernate.cache.use_query_cache">true</prop> 
     <prop key="hibernate.generate_statistics">true</prop> 
     <prop key="hibernate.cache.default_cache_concurrency_strategy">NONSTRICT_READ_WRITE</prop> 
     <prop key="hibernate.hbm2ddl.auto">update</prop> 
     <prop key="hibernate.jdbc.batch_size">1000</prop> 
     <prop key="hibernate.show_sql">false</prop> 
     <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> 
     <prop key="hibernate.search.default.directory_provider">filesystem</prop> 
     <prop key="hibernate.search.default.indexBase">/hibernate-search</prop> 
     </props> 
    </property> 
    </bean> 

Môi trường

  • JDK6
  • Linux x64
  • Hibernate 4.1.10
  • mùa xuân 3.2.1

UPDATE: Sử dụng @MappedSuperclass

@MappedSuperclass 
@Inheritance(strategy = InheritanceType.JOINED) 
public abstract class LongIdEntity { ... } 

Không thay đổi điều gì cả.

+0

Bạn có thể kiểm tra xem [câu hỏi này] (http://stackoverflow.com/questions/4452242/specifying-global-ehcache-capacity) không giải quyết cùng một vấn đề với sự cố bạn đang gặp phải không? – mindas

+0

Tôi đang cố gắng để đối diện thực sự. Anh ấy đang cố gắng để có một bộ nhớ cache lớn và tôi đang cố gắng để có một bộ nhớ cache cho mỗi thực thể. Hoặc ghi đè hành vi này bằng @Cache (region = ....). Nó được sử dụng để làm việc theo cách đó trong ngày đầu, nhưng ngày nay nó bị bỏ qua. –

Trả lời

7

Hibernate lưu trữ toàn bộ hệ thống phân cấp thực thể trong một khu vực một cách rõ ràng. Không có kiểm soát điều này. Đó là cách duy nhất để xử lý đúng cách độ phân giải bộ nhớ đệm đa hình được lưu trong bộ nhớ cache. Các nhà cung cấp khác (tôi nghĩ) cho phép một số kiểm soát đối với mỗi phân lớp được lưu trữ ở đâu/như thế nào (ít nhất đó là dự đoán của tôi dựa trên các tùy chọn được cung cấp bởi JPA).

+0

Không đúng sự thật. Tôi đã làm điều này trong quá khứ. Tôi đã có đề nghị thử một chiến lược thừa kế khác. Nhưng tôi không thấy những gì đã làm với bộ nhớ đệm thực sự. –

+6

Tôi là nhà phát triển chính của Hibernate. Tôi đảm bảo với bạn, nó lưu trữ toàn bộ hệ thống phân cấp được ánh xạ trong một vùng duy nhất. Và đã làm như vậy vì nó đã có bộ nhớ đệm;) –

+0

Nhìn vào https://forum.hibernate.org/viewtopic.php?f=1&t=1025577 :-) –

1

Tôi gặp sự cố này và tìm kiếm internet Tôi đã kết thúc trong luồng Stackoverflow này. Nó thực sự là hướng dẫn đối với tôi do tôi có cùng một vấn đề mà người ta giải thích trong câu hỏi này. Đọc cuộc thảo luận giữa Steve Ebersole và Jan Goyvaerts giải thích cho tôi về giải pháp của vụ án của tôi. Đặc biệt liên kết được cung cấp bởi một trong số chúng đến Hibernate forum.

Kiểm tra các khuyến nghị của diễn đàn (cũng đã qua ba năm từ câu hỏi này, có thể đã có sự thay đổi) Tôi đã thành công trong việc tạo các vùng lưu trữ khác nhau cho các trẻ khác nhau của một lớp cha.

Trong trường hợp của tôi, giải pháp đang sử dụng @MappedSuperclassxóa@Inheritance(strategy = InheritanceType.JOINED). Trong trường hợp này, tôi có thể thấy số lần truy cập chính xác trong các khu vực chính xác.

Để tham khảo, mã của tôi là tương tự như:

@MappedSuperclass 
public abstract class ParentObject implements Serializable { 
    .... 


@Entity 
@Cacheable(true) 
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
public class ChildObject extends ParentObject { 
    .... 

Bây giờ trong nhật ký tôi có thể thấy:

Cache: com.<...>.ChildObject store hit for com.<...>.ChildObject#52 

Thay vì:

Cache: com.<...>.ParentObject store hit for com.<...>.ParentObject#52 

Tất nhiên, thay đổi chú thích này có một hành vi khác nhau mà hành vi được sử dụng trong câu hỏi và không phải là chú thích trong một số trường hợp. Nhưng tôi vẫn nghĩ nó xứng đáng để cho nhận xét này ở đây là tham chiếu trong tương lai. Có thể có thể giúp người khác.

+0

Bạn có chắc chắn rằng '@Inheritance (strategy = InheritanceType.TABLE_PER_CLASS)' thực sự cần thiết? Lớp @MappedSuperclass không yêu cầu chú thích '@ Inheritance'. – Thierry

+0

Bạn nói đúng, nó nằm ngoài ví dụ này. Tôi sử dụng mã này để tránh tạo một bảng cho một số lớp trừu tượng trung gian do tôi đã quên thêm '@ MappedSuperclass' vào các lớp trung gian này. Tôi sửa nó cũng trong mã của tôi và tôi cập nhật câu trả lời này.Giải pháp không phải là đặt '@Inheritance (strategy = InheritanceType.TABLE_PER_CLASS)', nhưng loại bỏ '@Inheritance (strategy = InheritanceType.JOINED)' – JorgeHortelano

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