[英]Spring Data JPA map the stored procedure result to Non-Entity POJO from multiple data source
[英]select specific columns from the table and store the results to the non-entity POJO with Spring + hibernate + JPA
我正在使用Spring 3.1.3 + hibernate-entitymanager 5.0.7 (其中包含2.1版的JPA )+ ojdbc14-10.2.0.2.jar
我想從表中選擇特定的列,並將結果存儲到非實體POJO。 我想以以下鏈接中建議的方式實施
我的實體類:
@Entity
@Data
@Table(name = "CUSTOMER")
@SqlResultSetMapping(name="SampleMapping",
classes = {
@ConstructorResult(targetClass = com.entity.Sample.class,
columns = {@ColumnResult(name="customerId"), @ColumnResult(name="name"), @ColumnResult(name="firstName")}
)}
)
public class CustomerEntity {
@Id
@Column(name = "CUSTOMER_ID")
private String customerId;
@Column(name = "NAME")
private String name;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "AGE")
private String age;
}
我的查詢部分:
String q = "select s.customerId, s.name, s.firstName from CustomerEntity s";
Query query = entityManager.createNativeQuery(q,"SampleMapping");
List<Sample> resultsList = query.getResultSet();
示例類是簡單的POJO(帶有帶有customerId,name和firstName的參數化構造函數),我要在其中存儲查詢結果。
您能告訴我我需要添加哪個版本的Spring,Hibernate,JPA,ojdbc jars才能達到我的要求? 提前謝謝了。
如果以下異常是由於jar版本或注釋或查詢格式的任何不正確聲明所致,則無法識別。
因為添加以下罐子時幾乎沒有例外:
+- com.commons:commons-dao:jar:1.0## Heading ##-SNAPSHOT:compile
| +- oracle:ojdbc14:jar:10.2.0.2:compile
| +- org.springframework:spring-tx:jar:3.1.3.RELEASE:compile
| | +- aopalliance:aopalliance:jar:1.0:compile
| | \- org.springframework:spring-core:jar:3.1.3.RELEASE:compile
| +- org.springframework:spring-orm:jar:3.1.3.RELEASE:compile
| | \- org.springframework:spring-jdbc:jar:3.1.3.RELEASE:compile
| +- org.hibernate:hibernate-entitymanager:jar:5.0.7.Final:compile
| | +- org.hibernate:hibernate-core:jar:5.0.7.Final:compile
| | | +- antlr:antlr:jar:2.7.7:compile
| | | \- org.jboss:jandex:jar:2.0.0.Final:compile
| | +- dom4j:dom4j:jar:1.6.1:compile
| | +- org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile
| | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
| | \- org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1.1:compile
| +- org.javassist:javassist:jar:3.14.0-GA:compile
| +- javax.resource:connector:jar:1.0:compile
| | +- org.springframework:spring-oxm:jar:3.1.3.RELEASE:compile
| | \- org.apache.httpcomponents:httpclient-cache:jar:4.2.4:compile
| +- org.springframework:spring-beans:jar:3.1.3.RELEASE:compile (version managed from 3.1.2.RELEASE)
| +- org.springframework:spring-context:jar:3.1.3.RELEASE:compile (version managed from 3.1.2.RELEASE)
| | +- org.springframework:spring-expression:jar:3.1.3.RELEASE:compile
| | \- org.springframework:spring-asm:jar:3.1.3.RELEASE:compile
| +- org.slf4j:jcl-over-slf4j:jar:1.6.4:runtime
| \- org.slf4j:log4j-over-slf4j:jar:1.6.4:runtime
| +- org.springframework:spring-webmvc:jar:3.1.3.RELEASE:compile
| | \- org.springframework:spring-context-support:jar:3.1.3.RELEASE:compile
| +- org.springframework:spring-web:jar:3.1.3.RELEASE:compile
| +- org.springframework:spring-aop:jar:3.1.3.RELEASE:compile
| +- org.springframework.integration:spring-integration-core:jar:2.2.6.RELEASE:compile
| | \- org.springframework.retry:spring-retry:jar:1.0.2.RELEASE:compile
| +- org.springframework.integration:spring-integration-event:jar:2.2.6.RELEASE:runtime
| +- org.springframework.integration:spring-integration-file:jar:2.2.6.RELEASE:runtime
| +- org.springframework.integration:spring-integration-http:jar:2.2.6.RELEASE:compile
| +- org.springframework.integration:spring-integration-xml:jar:2.2.6.RELEASE:compile
| | \- org.springframework.ws:spring-xml:jar:2.1.1.RELEASE:compile
| +- org.springframework.integration:spring-integration-jms:jar:2.2.6.RELEASE:compile
| | \- org.springframework:spring-jms:jar:3.1.3.RELEASE:compile
| +- org.springframework.integration:spring-integration-ws:jar:2.2.6.RELEASE:compile
| | \- org.springframework.ws:spring-ws-core:jar:2.1.1.RELEASE:compile
+- org.hibernate:hibernate-validator:jar:4.3.0.Final:compile
+- log4j:log4j:jar:1.2.17:provided
+- org.slf4j:slf4j-api:jar:1.7.12:compile
+- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile
\- org.slf4j:slf4j-simple:jar:1.7.12:compile
但是我在以下行中導致以下異常
List<Sample> resultsList = query.getResultSet();
例外:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:635) ~[spring-orm-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:104) ~[spring-orm-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403) ~[spring-orm-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58) ~[spring-tx-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[spring-tx-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163) ~[spring-tx-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) ~[spring-aop-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at com.common.dao.SampleServiceImpl.sampleMethod(SrvImplemet.java:123) ~[commons-dao-1.0-SNAPSHOT.jar:na]
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.getResultSet(Loader.java:2116) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1899) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1875) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:919) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2611) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2594) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2423) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.Loader.list(Loader.java:2418) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:336) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1967) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:322) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:125) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606) ~[hibernate-entitymanager-5.0.7.Final.jar:5.0.7.Final]
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:483) ~[hibernate-entitymanager-5.0.7.Final.jar:5.0.7.Final]
at com.common.dao.SampleDaompl.sampleMethod.SampleDaoImpl.getData(SampleDaoImpl.java:16) ~[commons-dao-1.0-SNAPSHOT.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_51]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_51]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_51]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_51]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319) ~[spring-aop-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) ~[spring-aop-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[spring-aop-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155) ~[spring-tx-3.1.3.RELEASE.jar:3.1.3.RELEASE]
... 191 common frames omitted
Caused by: java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:799) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1039) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:839) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1132) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3329) ~[ojdbc14-10.2.0.2.jar:Oracle JDBC Driver version - "10.2.0.1.0"]
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:93) ~[commons-dbcp-1.2.2.jar:1.2.2]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) ~[hibernate-core-5.0.7.Final.jar:5.0.7.Final]
... 215 common frames omitted
注意:以前,當我嘗試選擇所有行並將結果存儲到具有依賴項Spring 3.1.3 + hibernate-entitymanager 3.5.3 + JPA 2.0 + ojdbc14-10.2.0.2.jar的實體類中時,我能夠獲取結果成功,沒有任何異常。
差異:
如果我理解您的問題正確,那么您已有一個包含以下各列的表
您想要創建一個實體,以便可以從該表中獲取數據。
首先要注意的是,所有JPA實體必須具有主鍵(@ID列)。 其次,我從來不需要使用@SqlResultSetMapping來工作。
在我們的系統中,我們有一個直接映射到一個實體的View,該實體與我們系統中的任何其他實體之間沒有區別,如果您不查看數據庫,您將不會知道沒有表(但是一個視圖)。
編輯我可以看到我錯過了部分問題。 因此,這就是您所要求的。
您需要查看一個JPQL構造函數表達式,它基本上允許您將所需的列選擇到您選擇的POJO中,但是POJO的構造函數必須能夠精確列出參數。
您可以使用條件和預測
Criteria query = session.createCriteria(CustomerEntity.class)
.setProjection(Projections.projectionList()
.add(Projections.property("customerId"), "customerId")
.add(Projections.property("name"), "name")
.add(Projections.property("firstName"), "firstName"));
query.setResultTransformer(new AliasToBeanResultTransformer(Sample.class));
List<Sample> list = query.list();
樣本類
public class Sample {
private String customerId;
private String name;
private String firstName;
public Sample(){
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
這是您可以執行的操作:
List<Sample> resultList = new ArrayList<>();
ResultSet rs = query.getResultSet();
while (rs.next()) {
ResultSetMetaData metadata = rs.getMetaData();
for (int i = 1; i <= metadata.getColumnCount(); i++) {
System.out.println("Column Name: " + metadata.getColumnName(i)
+ " | Value: " + rs.getObject(i));
}
Sample sample = new Sample();
sample.setSomeValue(rs.getObject(1));
sample.setSomeOtherValue(rs.getObject(2));
resultList.add(sample);
}
請注意,這里使用ResultSetMetaData
是可選的。 我用它來說明如何根據需要提取列名。
這是一種方法。
@Entity
@Table(name = "CUSTOMER")
@NamedNativeQuery(name = "findSampleMapping",
query = "SELECT CUSTOMER_ID, NAME, FIRST_NAME FROM CUSTOMER where CUSTOMER_ID = ?1", resultSetMapping = "SampleMapping")
@SqlResultSetMapping(name="SampleMapping",
classes = {
@ConstructorResult(targetClass = com.entity.Sample.class,
columns = {@ColumnResult(name="customerId"), @ColumnResult(name="name"), @ColumnResult(name="firstName")}
)}
)
public class CustomerEntity {
@Id
@Column(name = "CUSTOMER_ID")
private String customerId;
@Column(name = "NAME")
private String name;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "AGE")
private String age;
}
public class Sample {
private String customerId;
private String name;
private String firstName;
public Sample(String customerId, String name, String firstName){
this.customerId = customerId;
this.name = name;
this.firstName = firstName;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
Query q = em.createNamedQuery("findSampleMapping");
q.setParameter(1, "1");
@SuppressWarnings("unchecked")
List<Sample> list = q.getResultList();
for (Sample row : list) {
System.out.println(row.getCustomerId());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.