【问题标题】:"operator does not exist: uuid = bytea" Java with Postgres“操作员不存在:uuid = bytea”Java 与 Postgres
【发布时间】:2014-12-27 18:24:03
【问题描述】:

我在引用此查询时遇到问题。在 Postgres 上,这个查询执行没有错误。在 JAVA 上,它会抛出以下异常:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
cause
org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid = bytea
  Note: No operator matches the given name and argument type(s). You might need to add explicit type casts.
  Position: 404

我要做什么?

我的方法:

public List<CivilRecord> dashboardSearch(CivilRecordSearch civilRecordSearch)
    throws MessageException {
    SearchValidation.validateDashboardSearch(civilRecordSearch);
    List<CivilRecord> l = new ArrayList<>();
    try {
        StringBuilder query = new StringBuilder();
        // query.append("select
        // c.id_civil_record\\:\\:text,c.nm_request,c.nm_rg,c.tx_name,c.dt_register,c.bl_priority
        // ");
        query.append("select c.id_civil_record,c.nm_request,c.nm_rg,c.tx_name,c.dt_register,c.bl_priority ");
        query.append("from sc_civil.tb_civil_record c ");
        query.append("inner join sc_civil.tb_workflow_record w ");
        query.append("on w.id_civil_record = c.id_civil_record ");
        query.append("left join sc_civil.tb_lock l ");
        query.append("on l.id_record = c.id_civil_record ");
        query.append("where c.id_site = :idSite ");

        if (civilRecordSearch.getPriority() == null || civilRecordSearch.getPriority().equals(false))
            query.append("and c.bl_priority = :priority ");
        query.append("and c.bl_canceled = :canceled ");
        query.append("and w.id_type_workflow = :idTypeWorkflow ");
        query.append("and w.id_type_status_workflow = :idTypeStatusWorkflow ");

        query.append("and (l is null or l.id_user = :idUser) ");

        if (!StringUtils.isEmpty(civilRecordSearch.getName()))
            query.append("and c.tx_name ilike :name ");
        if (!StringUtils.isEmpty(civilRecordSearch.getRg()))
            query.append("and c.nm_rg like :rg ");

        if (civilRecordSearch.getRequestNumber() != null)
            query.append("and c.nm_request = :request ");

        query.append("order by c.bl_priority desc, c.dt_register ");

        Query q = em.createNativeQuery(query.toString());
        q.setParameter("idSite", civilRecordSearch.getSite().getId());
        if (civilRecordSearch.getPriority() == null || civilRecordSearch.getPriority().equals(false))
            q.setParameter("priority", false);
        q.setParameter("idTypeWorkflow", civilRecordSearch.getTypeworkflow().getId());
        q.setParameter("idTypeStatusWorkflow", civilRecordSearch.getTypestatusworkflow().getId());
        q.setParameter("idUser", civilRecordSearch.getIdUser());
        q.setParameter("canceled", false);
        if (!StringUtils.isEmpty(civilRecordSearch.getName()))
            q.setParameter("name", "%" + civilRecordSearch.getName() + "%");
        if (civilRecordSearch.getRequestNumber() != null)
            q.setParameter("request", civilRecordSearch.getRequestNumber());
        if (!StringUtils.isEmpty(civilRecordSearch.getRg()))
            q.setParameter("rg", civilRecordSearch.getRg());

        q.setMaxResults(maxResult);

        List<Object []> lo = q.getResultList();
        em.clear();
        for (Object [] o : lo) {
            CivilRecord c = new CivilRecord();
            c.setIdCivilRecord(UUID.fromString((String) o[0]));
            c.setRequest((Long) o[1]);
            c.setRg((String) o[2]);
            c.setName((String) o[3]);
            c.setWorkflowRecords(findStatus(c.getIdCivilRecord()));
            l.add(c);
        }
        return l;
    }
    catch (Exception e) {
        log.severe(e.getMessage());
        throw e;
    }
}

我的班级 CivilRecordSearch:

import java.io.Serializable;
import java.util.UUID;

public class CivilRecordSearch implements Serializable {

    private static final long serialVersionUID = 1701325902333490974L;

    // site, prioridade, tipo wf e status wf

    private Site site;
    private Boolean priority;
    private TypeWorkflow typeworkflow;
    private TypeStatusWorkflow typestatusworkflow;
    private Integer amount;
    private UUID idUser;
    private String name;
    private String rg;
    private Long requestNumber;

    public Site getSite() {
        return site;
    }

    public void setSite(Site site) {
        this.site = site;
    }

    public Boolean getPriority() {
        return priority;
    }

    public void setPriority(Boolean priority) {
        this.priority = priority;
    }

    public TypeWorkflow getTypeworkflow() {
        return typeworkflow;
    }

    public void setTypeworkflow(TypeWorkflow typeworkflow) {
        this.typeworkflow = typeworkflow;
    }

    public TypeStatusWorkflow getTypestatusworkflow() {
        return typestatusworkflow;
    }

    public void setTypeStatusWorkflow(TypeStatusWorkflow typestatusworkflow) {
        this.typestatusworkflow = typestatusworkflow;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public UUID getIdUser() {
        return idUser;
    }

    public void setIdUser(UUID idUser) {
        this.idUser = idUser;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRg() {
        return rg;
    }

    public void setRg(String rg) {
        this.rg = rg;
    }

    public Long getRequestNumber() {
        return requestNumber;
    }

    public void setRequestNumber(Long requestNumber) {
        this.requestNumber = requestNumber;
    }

}

【问题讨论】:

  • 数据库中tb_lock.idUser是什么类型?你可以试试q.setParameter("idUser", civilRecordSearch.getIdUser().toString())吗?
  • tb_lock.iduser 是 UUID 在数据库中。
  • 你在使用休眠吗?注释?
  • 是的。我正在使用休眠

标签: java postgresql select jpa


【解决方案1】:

不小心将null 作为参数传递也会导致相同的错误,然后将其视为bytea 类型,从而无法强制转换为uuid

所以,在进入上述解决方案之前,我建议检查一下自己的业务逻辑并快速激活application.yml中的休眠绑定参数日志:

logging:
  level:
    org:
      hibernate:
        type: TRACE

错误的论点变得明显,就像我的例子一样:

....
binding parameter [6] as [VARBINARY] - [null]
...

要查看 sql 查询,请添加:

spring:
  jpa:
    show-sql: true

【讨论】:

    【解决方案2】:

    问题:

    Hibernate 应该将 java UUID 类型映射到 postgress uuid 类型。但是,如果 hibernate 不知道如何映射它,它只会尝试序列化对象,从而导致byte[]。当然,这只是将问题转移到数据库级别。 uuid postgress 类型的值不能仅与字节数组类型进行比较。

    PSQLException: ERROR: operator does not exist: uuid = bytea
    

    可能原因:

    我在从 Spring Boot 1.x 迁移到 Spring Boot 2.3.0 时遇到了这个问题。在 Spring Boot 1.x 中,我用 @Id 标记我的 id 字段并使其成为 java 类型 UUID 就足够了。

    快速而肮脏的解决方案:

    一种可能的解决方案是显式声明 id 字段的 PSQL 类型。

     @Type(type="org.hibernate.type.PostgresUUIDType")
     @Id
     private UUID id;
    

    更好的解决方案是定义系统范围的替换。您可以将此声明放在任何类或包上。在某个地方只定义一次实际上会影响 UUID 的所有声明。

     @TypeDef(name="postgres-uuid",
              defaultForType = UUID.class,
              typeClass = PostgresUUIDType.class)
    

    真正的解决方案:

    查看您的日志文件,您可能会看到类似这样的内容。仔细检查此方言的版本,看看它是否与您在属性文件中定义的版本匹配:

    Dialect - HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL81Dialect
    

    在这种情况下,请注意以下属性已过时:

    hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
    

    一些休眠属性现在需要有一个spring.jpa.properties 前缀。所以,在这种情况下,新的属性路径应该是spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect

    这就是一切开始变得有意义的时刻。此方言为您完成所有必需的类型定义。

    【讨论】:

      【解决方案3】:

      对 Robson Silveira 的类似回应。

      注意查询字符串的最后一位。

      public Account getAccount(String name, String password, String tenantId) {
          Query q = em.createNativeQuery(
                  "SELECT a.id, a.name, a.password, a.email FROM accounts a WHERE name = :name and password = :password and tenant_fk = CAST(:tenant_fk AS uuid)"
          );
          q.setParameter("name", name);
          q.setParameter("password", password);
          q.setParameter("tenant_fk", tenantId);
      
          List<Object[]> results = q.getResultList();
          if (results.size() == 0) {
              return null;
          }
      
          return mapFromObject(results.get(0));
      }
      

      【讨论】:

        【解决方案4】:

        我用这个表格解决了我的问题: 我为我的 UUID 字段使用了命令 CAST

          public List<CivilRecord> dashboardSearch(CivilRecordSearch civilRecordSearch)
              throws MessageException {
            SearchValidation.validateDashboardSearch(civilRecordSearch);
            List<CivilRecord> l = new ArrayList<>();
            try {
              StringBuilder query = new StringBuilder();
              //query.append("select c.id_civil_record\\:\\:text,c.nm_request,c.nm_rg,c.tx_name,c.dt_register,c.bl_priority ");
              query.append("select CAST(c.id_civil_record as text),c.nm_request,c.nm_rg,c.tx_name,c.dt_register,c.bl_priority ");
              query.append("from sc_civil.tb_civil_record c ");
              query.append("inner join sc_civil.tb_workflow_record w ");
              query.append("on w.id_civil_record = c.id_civil_record ");
              query.append("left join sc_civil.tb_lock l ");
              query.append("on l.id_record = c.id_civil_record ");
              query.append("where c.id_site = :idSite ");
        
              if (civilRecordSearch.getPriority() == null || civilRecordSearch.getPriority().equals(false))
                query.append("and c.bl_priority = :priority ");
              query.append("and c.bl_canceled = :canceled ");
              query.append("and w.id_type_workflow = :idTypeWorkflow ");
              query.append("and w.id_type_status_workflow = :idTypeStatusWorkflow ");
        
              query.append("and (l is null or l.id_user = CAST(:idUser AS uuid)) ");
        
              if (!StringUtils.isEmpty(civilRecordSearch.getName()))
                query.append("and c.tx_name ilike :name ");
              if (!StringUtils.isEmpty(civilRecordSearch.getRg()))
                query.append("and c.nm_rg like :rg ");
        
              if (civilRecordSearch.getRequestNumber() != null)
                query.append("and c.nm_request = :request ");
        
              query.append("order by c.bl_priority desc, c.dt_register ");
        
              Query q = em.createNativeQuery(query.toString());
              q.setParameter("idSite", civilRecordSearch.getSite().getId());
              if (civilRecordSearch.getPriority() == null || civilRecordSearch.getPriority().equals(false))
                q.setParameter("priority", false);
              q.setParameter("idTypeWorkflow", civilRecordSearch.getTypeworkflow().getId());
              q.setParameter("idTypeStatusWorkflow", civilRecordSearch.getTypestatusworkflow().getId());
              q.setParameter("idUser", civilRecordSearch.getIdUser().toString());
              q.setParameter("canceled", false);
              if (!StringUtils.isEmpty(civilRecordSearch.getName()))
                q.setParameter("name","%" + civilRecordSearch.getName() + "%");
              if (civilRecordSearch.getRequestNumber() != null)
                q.setParameter("request", civilRecordSearch.getRequestNumber());
              if (!StringUtils.isEmpty(civilRecordSearch.getRg()))
                q.setParameter("rg", civilRecordSearch.getRg());
        
              q.setMaxResults(maxResult);
              List<Object[]> lo = q.getResultList();
              em.clear();
              for(Object[] o : lo){
                  CivilRecord c = new CivilRecord();
                  c.setIdCivilRecord(UUID.fromString((String)o[0]));
                  c.setRequest(((BigInteger)o[1]).longValue());
                  c.setRg((String)o[2]);
                  c.setName((String)o[3]);
                  c.setRegister((Date)o[4]);
                  c.setPriority(TypeYesNo.getByKey(((Boolean)o[5]).booleanValue()));
                  c.setWorkflowRecords(findStatus(c.getIdCivilRecord()));
                  l.add(c);
              }
              return l;
            } catch (Exception e) {
              log.severe(e.getMessage());
              throw e;
            }
          }
        

        【讨论】:

        • 为什么这是解决方案?
        猜你喜欢
        • 2014-09-13
        • 2016-02-28
        • 2010-10-20
        • 2013-07-31
        • 2021-02-24
        • 1970-01-01
        • 1970-01-01
        • 2023-01-08
        • 1970-01-01
        相关资源
        最近更新 更多