我在 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 映射如下所述
<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
我不明白出了什么问题。任何帮助将不胜感激。
我认为你应该检查你的变量“userName”不为空。我在类似的情况下经历过这条消息。
这个问题很旧,但如果有人需要的话,仍然分享我在 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。 如果列 1 和列 2 不为 NULL,则查询中将考虑列 1 和列 2。
?1 为 null 或 column1 = ?1 : 将检查传递的值是否为 null,然后整个 where 条件将为 true(如果为 null,则不会检查第二个条件 [column1 = null] - PG 优化)
cast(?1 AS text) :如果由于某种原因值作为 bytea 传递, 会很有用。如果传递的值是真正的 null,如果不进行强制转换,它仍然会给出“character Varying bytea”错误。
似乎 Hibernate 由于某种原因将类型参数作为 bytea (或者更确切地说,可能是 java.sql.Types.BLOB)发送,而不是将其留给服务器推断或将其设置为文本(java.sql.Types 。细绳)。 这是解决方案 参数上的 JPA lower() 函数的类似问题
对于本机查询,我们可以使用
SELECT * FROM table
WHERE
(:paramName is null OR column1 = cast(:paramName AS text))
然后
query.setParamter(paramName,value)
;
故障排除清单:
#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 中重新审视整个问题。
我希望这有帮助。欢呼与和平。
你可以做什么,首先将 null 参数转换为文本,然后将其与 '' 空字符串合并,这样你的代码就变成了
List list = getHibernateTemplate().find("from LoginDetails ld where COALESCE(ld.userName,'') =COALESCE(cast(? as TEXT),'')", userName);
我已经尝试过使用 Postgress 和 JPA 来解决这个问题
SQL 适配器从您的应用程序接收一个 Python
bytes
对象,并将其作为 PostgreSQL bytea
(rray) 值呈现到数据库。
Postgresql 没有 Pg
bytearrays
和 Pg varchars
之间的相等比较。它们不是同一类东西。第一个是不透明的、无法解释的数据,第二个应该是文本。
您可能想要做的是将 bytearray 或 Python
bytes
对象解码为 Python str
Unicode 对象,然后将其发送到您的查询中。 (当然,它从 Unicode 转换为某种编码,但您可以信任数据库适配器来处理该部分。)
假设您知道字节的编码是什么。
但是,如果您尝试发送到数据库的确实不是 Unicode 文本,那么您应该在 DDL 和表定义中选择一种不同的数据类型,一种非文本类型,例如 Pg
bytea
。