【问题标题】:Problem with a ORACLE LONG datatype field when searching for it with JPA使用 JPA 搜索 ORACLE LONG 数据类型字段时出现问题
【发布时间】:2019-10-19 09:40:02
【问题描述】:

已解决,请在底部阅读

我有一个名为“EmailTransmitido”的模型:

@Data
@Entity
@Builder
@Table(schema = "EMAIL", name = "EN_EMAIL_TRANSMITIDO")
public class EmailTransmitido extends EntidadeBase {
...
    @ManyToOne
    @JoinColumn(name = "NRO_EMAIL")
    private EmailMensagem emailMensagem;
...

还有一个叫“EmailMensagem”:

@Data
@Entity
@Table(schema = "EMAIL", name = "EN_MENSAGEM_EMAIL")
public class EmailMensagem extends EntidadeBase {

...
    @Column(name = "TXT_TITULO")
    private String txtTitulo;

    @Column(name = "TXT_MENSAGEM")
    private String txtMensagem;
...

然后我需要搜索这个字段“

@Repository
public interface EmailTransmitidoRepository extends JpaRepository<EmailTransmitido, Long> {

...
        @Query("SELECT et FROM EmailTransmitido et WHERE et.recursoHumano = ?1 "
                + "AND et.emailMensagem.txtMensagem LIKE %?2%")
        Page<EmailTransmitido> getMensagensNotArquivadasByEnRh(
                @Param("enRh") EnRh enRh, @Param("pesquisa") String pesquisa, Pageable pageable);
...

但我收到一个错误:

Hibernate: 
    select
        * 
    from
        ( select
            emailtrans0_.SEQ_EMAIL_TRANSMITIDO as SEQ_EMAIL_TRANSMIT1_5_,
            emailtrans0_.TXT_CAMPOS_MSG as TXT_CAMPOS_MSG2_5_,
            emailtrans0_.DTA_AGENDA as DTA_AGENDA3_5_,
            emailtrans0_.DTA_ULT_ATUALIZ as DTA_ULT_ATUALIZ4_5_,
            emailtrans0_.DTA_ENVIO as DTA_ENVIO5_5_,
            emailtrans0_.NRO_EMAIL as NRO_EMAIL6_5_,
            emailtrans0_.STA_EMAIL_TESTE as STA_EMAIL_TESTE7_5_,
            emailtrans0_.TXT_USERNAME_ULT_ATUALIZ as TXT_USERNAME_ULT_A8_5_,
            emailtrans0_.NRO_MODELO_DOC as NRO_MODELO_DOC9_5_,
            emailtrans0_.COD_RH as COD_RH17_5_,
            emailtrans0_.STA_EMAIL_TRANSMITIDO as STA_EMAIL_TRANSMI10_5_,
            emailtrans0_.TXT_CAMPOS_MSG_BKP as TXT_CAMPOS_MSG_BK11_5_,
            emailtrans0_.TXT_EMAIL as TXT_EMAIL12_5_,
            emailtrans0_.TXT_EMAIL_COPIA as TXT_EMAIL_COPIA13_5_,
            emailtrans0_.TXT_EMAIL_COPIA_OCULTA as TXT_EMAIL_COPIA_O14_5_,
            emailtrans0_.TXT_ERRO_TRANSMISSAO as TXT_ERRO_TRANSMIS15_5_,
            emailtrans0_.TXT_REMETENTE as TXT_REMETENTE16_5_ 
        from
            EMAIL.EN_EMAIL_TRANSMITIDO emailtrans0_ cross 
        join
            EMAIL.EN_MENSAGEM_EMAIL emailmensa1_ 
        where
            emailtrans0_.NRO_EMAIL=emailmensa1_.NRO_EMAIL 
            and emailtrans0_.COD_RH=? 
            and (
                TO_CLOB(emailmensa1_.TXT_MENSAGEM) like ?
            ) 
        order by
            emailtrans0_.SEQ_EMAIL_TRANSMITIDO desc ) 
    where
        rownum <= ?
2019-06-03 16:49:12.542  WARN 10560 --- [nio-9500-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 932, SQLState: 42000
2019-06-03 16:49:12.542 ERROR 10560 --- [nio-9500-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : ORA-00932: tipos de dados inconsistentes: esperava CHAR obteve LONG

2019-06-03 16:49:12.549 ERROR 10560 --- [nio-9500-exec-2] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [/cm-api] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause

java.sql.SQLSyntaxErrorException: ORA-00932: tipos de dados inconsistentes: esperava CHAR obteve LONG

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:208) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:886) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1175) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1296) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3613) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3657) ~[ojdbc6.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1495) ~[ojdbc6.jar:11.2.0.4.0]
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-3.2.0.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-3.2.0.jar:na]
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2167) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1930) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1892) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.doQuery(Loader.java:937) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:340) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.doList(Loader.java:2689) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.doList(Loader.java:2672) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2506) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.Loader.list(Loader.java:2501) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:395) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:220) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1508) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1537) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1505) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.query.Query.getResultList(Query.java:135) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:194) ~[spring-data-jpa-2.1.5.RELEASE.jar:2.1.5.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:91) ~[spring-data-jpa-2.1.5.RELEASE.jar:2.1.5.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:136) ~[spring-data-jpa-2.1.5.RELEASE.jar:2.1.5.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:125) ~[spring-data-jpa-2.1.5.RELEASE.jar:2.1.5.RELEASE]

这种错误“java.sql.SQLSyntaxErrorException:ORA-00932:tipos de dados 不一致:esperava CHAR obteve LONG”意味着“预期的 CHAR 得到 LONG”与LONG datatype in Oracle be deprecated?我的意思是,使用不同数据类型的其他字段适用于类似的搜索查询。

我尝试使用@Formula 而不是@Column,但是没有用:

@Formula("TOCLOB(TXT_MENSAGEM)")
private String txtMensagem;

我也尝试使用 JPQ Query 方法,但问题仍然存在,只有这个特定的 LONG 字段。我的主要问题是我无法更改 Oracle 中的数据类型,因为它是客户端的旧数据库,我只能从中读取,而且我无权在那里进行更改,所以有一些解决方法可以将此字段与JPA?

我通过创建另一个表以将这些数据保存为 CLOB 格式解决了这个问题。由于该列具有固定值并且消费者没有反对它。需要在这里说,我搜索了很多,似乎还没有一个好的解决方法,所以如果你也遇到这个问题,考虑做同样的事情或明确地改变你的列数据类型。感谢大家的帮助。

【问题讨论】:

  • 是的,LONG 列已被弃用。请参阅documentation - The LONG RAW datatype is provided for backward compatibility with existing applications. For new applications, use the BLOB and BFILE datatypes for large amounts of binary data. 中的此说明。只需将该列转换为 BLOB - 如果您想在其中存储文本数据,也可以转换为 CLOB(LONG 和 BLOB 用于存储二进制原始数据,而不是文本)。

标签: oracle hibernate jpa spring-data-jpa jpql


【解决方案1】:

你应该能够像 LOB 一样映射 Long:

@Lob
@Column(name = "TXT_MENSAGEM")
private String txtMensagem;

【讨论】:

  • 感谢您的回复。我尝试了@Lob,但问题仍然存在。我可以得到该字段,但我无法使用 LIKE 运算符搜索它,每当我尝试时我仍然收到它:ORA-00932:不一致的数据类型:预期的 CHAR 得到 LONG
  • 你设置了哪种休眠方言?
猜你喜欢
  • 2015-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 2015-11-30
相关资源
最近更新 更多