我如何看待Hibernate如何将pojo映射到sql结果?

时间:2018-02-23 21:18:40

标签: java hibernate

这是我使用Hibernate从数据库获取FrameFactory列表的代码

@SuppressWarnings("unchecked")
@Override
public List<FrameFactory> getFrameFactoryByActiveYN(Boolean activeYN) {
    String sql = sqlProperties.getProperty("getFrameFactoryByActiveYN");
    SQLQuery q = getSession().createSQLQuery(sql);
    q.addEntity(FrameFactory.class);
    q.setParameter("activeYN",activeYN,BooleanType.INSTANCE);
    List<?> uncast = q.list(); // <---- exception here
    System.out.println(Arrays.toString(uncast.toArray()));
    List<FrameFactory>frameFactorys = (List<FrameFactory>)q.list(); // <---- exception also here
    return frameFactorys;
}

我的sqlPropertiesFile

getFrameFactoryByActiveYN=SELECT * FROM TBLFRAMEFACTORY WHERE FRAMEFACTORY_ACTIVEYN \= \:activeYN

我的FrameFactory类

@Entity
@Table(name="TBLFRAMEFACTORY")
public class FrameFactory extends Auditable implements Serializable {

private static final long serialVersionUID = 1L;

@Type(type="yes_no")
@NotNull
@Column(name="FRAMEFACTORY_ACTIVEYN")
protected Boolean activeYN = false;
@Id
@Column(name="FRAMEFACTORY_CLASSPATH", updatable=false, nullable=false)
protected String classPath = null;

public FrameFactory() { super(); }

public FrameFactory(FrameFactory frameFactory) {
    setActiveYN(frameFactory.getActiveYN());
    setClassPath(frameFactory.getClassPath());
}

public Boolean getActiveYN() {
    return activeYN;
}

public void setActiveYN(Boolean activeYN) {
    this.activeYN = activeYN;
}

public String getClassPath() {
    return classPath;
}

public void setClassPath(String classPath) {
    this.classPath = classPath;
}

@Transient
@Override
public String getPrimaryKeyDisplay() {
    StringBuilder sb = new StringBuilder();
    if (classPath == null) {
        sb.append(" classPath: null");
    } else {
        sb.append(" classPath: " + classPath.toString());
    }
    return sb.toString();
}
@Transient
@Override
public String toString() {
    return new ToStringBuilder(this).append("activeYN", activeYN).append("classPath", classPath).toString();
}

@Transient
@Override
public int hashCode() {
    return new HashCodeBuilder().append(activeYN).append(classPath).toHashCode();
}

@Transient
@Override
public boolean equals(Object obj) {
    if (obj == null) { return false; }
    if (obj == this) { return true; }
    if (obj.getClass() != getClass()) { return false; }
    FrameFactory that = (FrameFactory) obj;
    return new EqualsBuilder().append(activeYN, that.activeYN).append(classPath, that.classPath).isEquals();
}

}

我的Auditable类

public abstract class Auditable {
@Transient
protected Integer auditContactId = null;

public void setAuditContactId(Integer auditContactId) {
    this.auditContactId = auditContactId;
}

public Integer getAuditContactId() {
    return auditContactId;
}

public abstract String getPrimaryKeyDisplay();
}

我的服务器上出现以下异常

WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (EJB default - 6) SQL Error: 1722, SQLState: 42000
ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (EJB default - 6) ORA-01722: invalid number

我理解异常是试图告诉我它无法强制转换为数字。但是我不期待一个数字,我期望在db中映射的布尔值为char(1)'Y'或'N',并且在db中将String映射为VarChar2(256)。我想看看Hibernate在尝试将数据从ResultSet映射到FrameFactory对象时在幕后做了什么。有什么建议吗?

以下是所请求的完整堆栈跟踪。

 16:48:20,250 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (EJB default - 3) SQL Error: 1722, SQLState: 42000
 16:48:20,251 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (EJB default - 3) ORA-01722: invalid number

 16:48:20,253 ERROR [org.jboss.as.ejb3.invocation] (EJB default - 3) JBAS014134: EJB Invocation failed on component KdsSessionBean for method public abstract java.util.List com.kable.newsstand.kdsejb.session.KdsSession.getFrameFactoryByActiveYN(java.lang.Boolean): javax.ejb.EJBException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
       at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:190) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:280) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:330) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:242) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.remote.EJBRemoteTransactionPropagatingInterceptor.processInvocation(EJBRemoteTransactionPropagatingInterceptor.java:79) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:43) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:89) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) [jboss-as-ee.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:55) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45) [jboss-as-ee.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:185) [jboss-as-ee.jar:7.5.8.Final-redhat-2]
       at org.jboss.as.ejb3.remote.protocol.versionone.MethodInvocationMessageHandler.invokeMethod(MethodInvocationMessageHandler.java:319) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.as.ejb3.remote.protocol.versionone.MethodInvocationMessageHandler.access$100(MethodInvocationMessageHandler.java:68) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.as.ejb3.remote.protocol.versionone.MethodInvocationMessageHandler$1.run(MethodInvocationMessageHandler.java:201) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:473) [rt.jar:1.7.0_141]
       at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_141]
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_141]
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_141]
       at java.lang.Thread.run(Thread.java:748) [rt.jar:1.7.0_141]
       at org.jboss.threads.JBossThread.run(JBossThread.java:122)
 Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
       at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:82) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:88) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.getResultSet(Loader.java:2064) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1861) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1840) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.doQuery(Loader.java:905) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:347) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.doList(Loader.java:2552) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.doList(Loader.java:2538) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2368) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.Loader.list(Loader.java:2363) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:340) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1788) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:232) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:157) [hibernate-core.jar:4.2.23.Final-redhat-1]
       at com.kable.newsstand.kdsejb.session.KdsSessionBean.getFrameFactoryByActiveYN(KdsSessionBean.java:3523) [kdsSession.jar:]
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_141]
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_141]
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_141]
       at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_141]
       at org.jboss.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52) [jboss-as-ee.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63) [jboss-as-ee.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63) [jboss-as-ee.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.component.invocationmetrics.ExecutionTimeInterceptor.processInvocation(ExecutionTimeInterceptor.java:43) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.jpa.interceptor.SBInvocationInterceptor.processInvocation(SBInvocationInterceptor.java:47) [jboss-as-jpa.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:53) [jboss-as-ee.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.component.pool.PooledInstanceInterceptor.processInvocation(PooledInstanceInterceptor.java:51) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation.jar:1.1.2.Final-redhat-1]
       at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:278) [jboss-as-ejb3.jar:7.5.8.Final-redhat-2]
       ... 32 more
 Caused by: java.sql.SQLSyntaxErrorException: ORA-01722: invalid number

       at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
       at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
       at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
       at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
       at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
       at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
       at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
       at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
       at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:774)
       at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:925)
       at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1111)
       at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)
       at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:4845)
       at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1501)
       at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:462)
       at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) [hibernate-core.jar:4.2.23.Final-redhat-1]
       ... 70 more

我尝试将我的方法代码更改为以下内容,它仍会返回相同的异常。

@SuppressWarnings("unchecked")
@Override
public List<FrameFactory> getFrameFactoryByActiveYN(Boolean activeYN) {
    String sql = sqlProperties.getProperty("getFrameFactoryByActiveYN");
    SQLQuery q = getSession().createSQLQuery(sql);
//      q.addEntity(FrameFactory.class);
    q.setParameter("activeYN",activeYN,BooleanType.INSTANCE);
    q.addScalar("FRAMEFACTORY_ACTIVEYN", BooleanType.INSTANCE).addScalar("FRAMEFACTORY_CLASSPATH", StringType.INSTANCE).setResultTransformer(new AliasToBeanResultTransformer(FrameFactory.class));
    List<FrameFactory>frameFactorys = (List<FrameFactory>)q.list();
    return frameFactorys;
}

2 个答案:

答案 0 :(得分:0)

根据http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#objectstate-querying-nativesql,您应该重写您的原生SQL查询:

getFrameFactoryByActiveYN=SELECT {f.*} FROM TBLFRAMEFACTORY f WHERE FRAMEFACTORY_ACTIVEYN \= \:activeYN

答案 1 :(得分:0)

事实证明问题不是映射到结果。它接受布尔值作为查询参数。我试过把

<property name="hibernate.query.substitutions" value="true 'Y', false 'N'" />
persistence.xml中的

,但是没有用。所以我的工作是检测布尔SQL参数并将其更改为“&#39; /&#39; N&#39;之一。值。如下所示。

@SuppressWarnings("unchecked")
@Override
public List<FrameFactory> getFrameFactoryByActiveYN(Boolean activeYN) {
    String sql = sqlProperties.getProperty("getFrameFactoryByActiveYN");
    SQLQuery q = getSession().createSQLQuery(sql);
    q.addEntity(FrameFactory.class);
    q.setParameter("activeYN", activeYN == null ? "N" : activeYN ? "Y" : "N", StringType.INSTANCE);
    List<FrameFactory>frameFactorys = q.list();
    return frameFactorys;
}