“运算符不存在:uuid = bytea”与Postgres的Java

时间:2014-10-31 12:19:09

标签: java postgresql select jpa

我在引用此查询时遇到问题。在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;
    }

}

3 个答案:

答案 0 :(得分:8)

我用这个表单解决了我的问题: 我将命令CAST用于我的UUID字段

  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;
    }
  }

答案 1 :(得分:0)

对Robson Silveira的类似回应。

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

  const projectId = 'test-bot-test-1111';
  const sessionId = user.uuid;
  const languageCode = 'en-GB';

  const sessionClient = new dialogFlow.SessionsClient();
  const sessionPath = sessionClient.sessionPath(projectId, sessionId);

const request = {
    session: sessionPath,
    queryInput: {
      event: {
        name: 'custom_event',
        languageCode,
        parameters: {
          name: 'sam',
          user_name: 'sam',
          a: 'saaaa'
        }
      }
    },
    queryParams: {
      payload: {
        data: user
      }
    }
  };

  let resultReq;

  console.log('request :: ', request, '\n\n');

  try {
    resultReq = await sessionClient.detectIntent(request);
  } catch (err) {
    // eslint-disable-next-line no-console
    return console.error('ERROR:', err);
  }

答案 2 :(得分:0)

问题:

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

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

这就是一切开始变得有意义的地步。该方言可以为您完成所有必需的类型定义。