17

我在 postgres 中有一个具有以下结构的表

CREATE TABLE rpaul."HK_LOGIN_DETAILS"
(
  "HK_LOGIN_DETAILS_ID" bigint NOT NULL,
  "HK_LOGIN_DETAILS_USERNAME" character varying(10) NOT NULL,
  "HK_LOGIN_DETAILS_PASSWORD" character varying(50) NOT NULL,
  CONSTRAINT "HK_LOGIN_DETAILS_PK" PRIMARY KEY ("HK_LOGIN_DETAILS_ID" ),
  CONSTRAINT "HK_LOGIN_DETAILS_UK" UNIQUE ("HK_LOGIN_DETAILS_USERNAME" )
)

该表的休眠映射如下所述

<hibernate-mapping package="net.rpaul.projects.homekeeping.domain.login">
    <class name="LoginDetails" table="`HK_LOGIN_DETAILS`">
        <id name="id" column="`HK_LOGIN_DETAILS_ID`" type="long">
            <generator class="assigned" />
        </id>
        <property name="userName" type="string" column="`HK_LOGIN_DETAILS_USERNAME`" not-null="true" />
        <property name="password" type="string" column="`HK_LOGIN_DETAILS_PASSWORD`" not-null="true" />
    </class>
</hibernate-mapping>

在 LoginDetails.java 中,我将 id 字段声明为 long,将 userName 和 password 字段声明为 String。仍然当我尝试执行以下操作时

List list =  getHibernateTemplate().find("from LoginDetails ld where ld.userName = ?", userName);

我明白了

错误:运算符不存在:字符变化 = bytea

我不明白出了什么问题。任何帮助,将不胜感激。

4

5 回答 5

20

我认为您应该检查您的变量“userName”是否不为空。在这种情况下,我遇到了这个消息。

于 2012-06-12T21:24:36.920 回答
5

似乎 Hibernate 出于某种原因将类型参数作为 bytea(或者更确切地说,可能是 java.sql.Types.BLOB)发送,而不是让服务器推断或将其设置为文本(java.sql.Types.细绳)。这是与参数上的解决方案 JPA lower() 函数类似的问题

于 2015-09-29T10:33:56.133 回答
4

这个问题很老,但如果有人需要,我仍然分享我在 Spring Boot 中使用的解决方案。

您可以使用以下 WHERE 条件来处理 NULL 值或在 Postgres 查询中使参数可选。

SELECT * FROM table 
WHERE 
          (?1 is null OR column1 = cast(?1 AS text)) 
          AND 
          (?2 is null OR column2 = cast(?2 AS text))

如果 column1 和 column2 作为 NULL 传递,则此处整个 WHERE 条件将为 TRUE。如果不是 NULL,则在查询中将考虑 column1 和 column2。

?1 为空或 column1 = ?1 :将检查传递的值是否为空,然后整个 where 条件为真(如果为空,则不检查第二个条件 [column1 = null] - PG 优化)

cast(?1 AS text) :如果由于某种原因将值作为 bytea 传递,则可能很有用。如果传递的值是真正的 null,如果不强制转换,它仍然会给出“字符变化 bytea”错误。

于 2020-11-03T11:59:51.947 回答
2

对于本机查询,我们可以使用

SELECT * FROM table 
WHERE 
          (:paramName is null OR column1 = cast(:paramName AS text)) 

接着

query.setParamter(paramName,value);

于 2021-02-23T14:47:28.660 回答
0

故障排除清单:

#1:根据您使用的数据库类型,您可能希望使用以下 SQL 命令查找列名及其各自的数据类型:

SELECT
   table_name,
   column_name,
   data_type
FROM
   information_schema.columns
WHERE
   table_name = 'the-name-of-the-table-in-the-database';

预期结果将为您提供三列;尤其是“data_type”列。

确保您的 Pojo 类和相应的数据类型正确匹配。

注意:数据库里面的表中的bigint(数据类型)可以与Long无缝匹配。带 int 的整数。字符随 String 或主要的 java 类而变化,例如。一个存储枚举的类,等等。

确认上述后,进行下一步检查 -> 故障排除:

#2:此故障排除的主要检查是检查所有数据类型是否完全匹配。并注意传递给查询的参数。

传递枚举或任何其他数据类型或不符合 SQL 数据类型的枚举类型可能会触发“未映射”错误,即使 pojo 类与数据库中的表结构完全匹配。

pojo 示例:UserAccountBalance.class

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

@Builder//Lombok
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Data//Lombok
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Schema
@Entity(name = "user_account_balance")
@Table(name = "user_account_balance")
public class UserAccountBalance {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private long id;

    @NotNull
    @Column(name = "username", nullable = false)
    private String userName;

    @NotNull
    @Column(name="currency_code", nullable = false)
    @Enumerated(EnumType.STRING)
    private CurrencyCode currencyCode;

    @NotNull
    @Column(name = "balance", nullable = false)
    private BigDecimal balance;

//Could be placed into and AuditModel class
    @Column(name = "datecreated", nullable = false, updatable = false)
    @JsonIgnore
    @DateCreated
    @CreationTimestamp
    private LocalDateTime dateCreated;

    @Column(name = "date_updated", nullable = false, updatable = false)
    @JsonIgnore
    @DateUpdated
    private LocalDateTime dateUpdated;

    @NotNull
    @Column(name = "active")
    @JsonIgnore
    private int active;

    @Column(name = "deleted")
    @JsonIgnore
    private int deleted;

}

存储库类:

//选项1:UserAccountBalanceRepository.class

@Repository
public abstract class UserAccountBalanceRepository implements CrudRepository<UserAccountBalance, Long> {

    private final EntityManager entityManager;

    public UserAccountBalanceRepository(@CurrentSession EntityManager entityManager){
        this.entityManager = entityManager;
    }

    @Transactional(readOnly = true)
    @Query(
            value="SELECT uab.*" +
                    " FROM public.user_account_balance uab" +
                    " WHERE (currency_code =cast(:currencyCode AS text)" +
                    " AND userName =:userName" +
                    " AND active =:active)",
            countQuery = "SELECT uab.*" +
                    " FROM public.user_account_balance uab" +
                    " WHERE (currency_code = cast(:currencyCode AS text)" +
                    " AND userName =:userName" +
                    " AND active =:active)",
            nativeQuery = true
    )
    public abstract Optional<UserAccountBalance> findByUserAccountBalance_UserName_And_CurrencyCode(
            String userName,
            CurrencyCode currencyCode,
            int active
    );

}

//选项2:UserAccountBalanceRepository.class

@Repository
public abstract class UserAccountBalanceRepository implements CrudRepository<UserAccountBalance, Long> {

    private final EntityManager entityManager;

    public UserAccountBalanceRepository(@CurrentSession EntityManager entityManager){
        this.entityManager = entityManager;
    }

    @Transactional(readOnly = true)
    @Query(
            value="SELECT uab.*" +
                    " FROM public.user_account_balance uab" +
                    " WHERE (currency_code =:currencyCode" +
                    " AND userName =:userName" +
                    " AND active =:active)",
            countQuery = "SELECT uab.*" +
                    " FROM public.user_account_balance uab" +
                    " WHERE (currency_code = :currencyCode" +
                    " AND userName =:userName" +
                    " AND active =:active)",
            nativeQuery = true
    )
    public abstract Optional<UserAccountBalance> findByUserAccountBalance_UserName_And_CurrencyCode(
            String userName,
            String currencyCode,/*this is what truly worked out for me perfectly*/
            int active
    );

}

#3。测试并再次测试。如果问题仍然存在,请耐心等待并再次查看所有变量和类。

#4。如果使用选项 #3 进行故障排除仍然没有帮助,请考虑散散步,稍作休息,并以全新的眼光从故障排除 #1 中重新审视它。

我希望这有帮助。欢呼与和平。

于 2021-08-24T14:37:31.350 回答