2016-10-24 20 views
6

Tôi nhận lỗiHibernate ehcache KHÔNG làm việc cho truy vấn SQL Native bộ nhớ cache

aliases expected length is 1; actual length is 4 
    at org.hibernate.transform.CacheableResultTransformer.transformTuple 

tôi có cấu hình JPA + Hibernate và bộ nhớ cache truy vấn và bộ nhớ cache mức thứ hai sử dụng Eh-Cache.

Cấu hình: PostgreSQL 9.6 + JPA 2.1 + Hibernate 5.2.3.Final

Tôi cố gắng để thực hiện NativeQuery với SqlResultSetMapping [tùy chỉnh tập hợp kết quả lớp]. Mọi thứ đều hoạt động tốt khi tôi tắt bộ nhớ cache.

Tuy nhiên, nhận được lỗi trên khi tôi bật bộ nhớ cache. Bộ nhớ cache hoạt động tốt ngoại trừ NativeQuery.

Bảng SCHEMA:

PK first second third 

1 A  abc  C  
2 A  abc  C  
3 A  xyz  D  
4 B  abc  C  
5 B  xyz  C  
6 B  abc  D  
7 A  xyz  C  
8 A  abc  D  

SQL Native QUERY:

SELECT t.first,t.second, 
    COUNT(t.second) total, 
    COALESCE(t1.ccount, 0) ccount, 
    COALESCE(t2.dcount, 0) dcount 
FROM test t 
LEFT JOIN (SELECT 
    COUNT(third) AS ccount, FIRST, SECOND 
    FROM test 
    WHERE third = 'C' 
    GROUP BY SECOND,FIRST) t1 
ON (t1.first = t.first AND t1.SECOND = t.SECOND) 
LEFT JOIN (SELECT 
    COUNT(third) AS dcount, FIRST, SECOND 
    FROM test 
    WHERE third = 'D' 
    GROUP BY SECOND,FIRST) t2 
ON (t2.first = t.first AND t2.SECOND = t.SECOND) 
GROUP BY t.SECOND, t.first; 

SqlResultSetMapping

@SqlResultSetMapping(name = "RESULT_SET_NAME", classes = { 
     @ConstructorResult(targetClass = TestResult.class, 
      columns = { @ColumnResult(name = "first", type = String.class), 
         @ColumnResult(name = "second", type = String.class), 
         @ColumnResult(name = "total", type = String.class), 
         @ColumnResult(name = "ccount", type = String.class), 
         @ColumnResult(name = "dcount", type = String.class) }) }) 

query = getEntityManager().createNativeQuery(nativeQuery, "RESULT_SET_NAME"); 
query.setHint("org.hibernate.cacheable", true); 
result = query.getResultList(); 

Dự kiến ​​kết quả thiết lập

first second total ccount dcount 
------ ------ ------ ------ -------- 
A  abc   3  2   1 
B  abc   2  1   1 
A  xyz   2  1   1 
B  xyz   1  1   0 

stack trace

aliases expected length is 1; actual length is 4 
java.lang.IllegalStateException: aliases expected length is 1; actual length is 4 
    at org.hibernate.transform.CacheableResultTransformer.transformTuple(CacheableResultTransformer.java:155) 
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:770) 
    at org.hibernate.loader.Loader.processResultSet(Loader.java:985) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:943) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) 
    at org.hibernate.loader.Loader.doList(Loader.java:2615) 
    at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2460) 
    at org.hibernate.loader.Loader.list(Loader.java:2422) 
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335) 
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2129) 
    at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:981) 
    at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:147) 
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1398) 
    at org.hibernate.Query.getResultList(Query.java:417) 
+1

GÌ truy vấn? GÌ ngăn xếp dấu vết? Cấu hình gì? API nào gọi? –

+0

@BillyFrost, tôi đã thêm tất cả chi tiết, vui lòng kiểm tra câu hỏi đã chỉnh sửa, vui lòng cho tôi biết – Kunal

+0

Tôi đã sửa đổi ConstructorResultNativeQueryTest để sử dụng ví dụ bạn đã cung cấp, nhưng nó hoạt động không có lỗi. http://pastebin.com/Cj5YntaC đặt JAVA_HOME của bạn thành đường dẫn JDK8 và chạy với './gradlew hibernate-core: test --tests * ConstructorResultNativeQueryTest -Pdb = pgsql' (giả sử bạn đã thiết lập một cơ sở dữ liệu' hibernate_orm_test 'và người dùng có cùng tên và mật khẩu và toàn quyền truy cập vào nó). Tôi không thể sao chép lỗi của bạn. – coladict

Trả lời

1

Trong trường hợp của bạn, EHCache chỉ có thể được sử dụng với truy vấn JPQL. Điều đó cũng có nghĩa là bạn sẽ phải viết lại truy vấn của mình để không sử dụng các lựa chọn con, công đoàn hoặc các cấu trúc sql nguyên gốc tương tự.

0

Hibernate không thể biết bạn đang làm gì khi bạn thực hiện truy vấn sql gốc và do đó không thể biết bộ nhớ cache nào cần được vô hiệu. Miễn là ngủ đông không biết bộ đệm nào bị ảnh hưởng, nó phải giả định rằng tất cả dữ liệu không hợp lệ để đảm bảo tính nhất quán của dữ liệu. Điều này có nghĩa là hibernate sẽ làm mất hiệu lực tất cả cache.

Fortunatly API hibernate cho phép bạn chỉ định các thực thể hoặc không gian truy vấn bị ảnh hưởng bởi truy vấn của bạn. Nói với hibernate rằng các bảng bị ảnh hưởng bởi truy vấn của bạn và hibernate sẽ chỉ làm mất hiệu lực cache dựa trên dữ liệu đó.

SQLQuery sqlQuery = session.createSQLQuery("UPDATE CUSTOMER SET ... WHERE ..."); 
sqlQuery.addSynchronizedEntityClass(Person.class); 
int updatedEntities = sqlQuery.executeUpdate(); 

với tên thực thể

sqlQuery.addSynchronizedEntityClass(Person.class); 
sqlQuery.addSynchronizedEntityName("com.link_intersystems.xhibernate.testclasses.Person"); 
sqlQuery.addSynchronizedQuerySpace("SOME_TABLE"); 

Đôi khi bạn muốn thực hiện một truy vấn nguồn gốc mà không làm thay đổi bất kỳ dữ liệu.Để ngăn không cho ngủ đông làm mất hiệu lực bộ nhớ cache cấp thứ hai, bạn có thể thêm đồng bộ hóa không gian truy vấn trống.

SQLQuery sqlQuery = session.createSQLQuery("ALTER SESSION SET NLS_COMP = 'BINARY'"); 
sqlQuery.addSynchronizedQuerySpace(""); 
/* 
* Only the empty query space "" will be invalidated. 
* So no cache will be invalidated, because no table with an empty name exists 
*/ 
int updatedEntities = sqlQuery.executeUpdate(); 

trong ngủ đông mapping xml

<sql-query name="setNLSCompBinary"> 
<!-- an empty synchronize tag prevents hibernate from invalidating second level caches --> 
<synchronize table="" /> 
    ALTER SESSION SET NLS_COMP = 'BINARY' 
</sql-query> 

impact-of-native-sql-queries-on-hibernates-second-level-cache

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