当前位置: 首页 > 知识库问答 >
问题:

使用EclipseLink和Querydsl自定义数据类型

阎涵容
2023-03-14

我创建了一个自定义数据类型,用于存储有效和规范化的电子邮件地址:

public class Email implements Serializable {

    private final String value;

    public Email(String emailAddress) {
        this.value = normalize(emailAddress);
        if (!isValid(value)) {
            throw new IllegalArgumentException("Email address format is not valid: " + value);
        }
    }
    ...
}

及其相应的JPA2.1转换器,用于自动向数据库存储和从数据库检索:

@Converter(autoApply = true)
public class EmailConverter implements AttributeConverter<Email, String> {

    @Override
    public String convertToDatabaseColumn(Email email) {
        return email == null ? null : email.toString();
    }

    @Override
    public Email convertToEntityAttribute(String email) {
        return email == null ? null : new Email(email);
    }

}

现在,我可以将它用作person实体的属性:

public class Person extends BaseEntity {

    private String name;

    private LocalDate birthDate;

    @QueryType(PropertyType.STRING)
    private Email email;

    ...
}

这个效果很好。但我有一个问题,当我试图找到所有人的电子邮件地址开始使用QueryDSL。我已经用@querytype作为字符串注释了email属性。这样,就可以创建Querydsl元模型,使我能够进行查询(使用.startswith()),如下所示:

private static final QPerson person = QPerson.person;

public List<Person> getEmailStartWith(String pattern) {
    pattern = Email.normalize(pattern);
    return new JPAQuery(getEntityManager())
        .from(person)
        .where(person.email.startsWith(pattern))
        .orderBy(person.email.asc())
        .list(person);
}

但运行时会出现以下异常:

java.lang.IllegalArgumentException: You have attempted to set a value of type class java.lang.String for parameter 1 with expected type of class xxx.Email from query string select person
from Person person
where person.email like ?1 escape '!'
order by person.email asc.
at org.eclipse.persistence.internal.jpa.QueryImpl.setParameterInternal(QueryImpl.java:932) ~[eclipselink-2.5.0.jar:2.5.0.v20130507-3faac2b]
at org.eclipse.persistence.internal.jpa.QueryImpl.setParameterInternal(QueryImpl.java:906) ~[eclipselink-2.5.0.jar:2.5.0.v20130507-3faac2b]
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:469) ~[eclipselink-2.5.0.jar:2.5.0.v20130507-3faac2b]
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:1) ~[eclipselink-2.5.0.jar:2.5.0.v20130507-3faac2b]
at com.mysema.query.jpa.impl.JPAUtil.setConstants(JPAUtil.java:44) ~[querydsl-jpa-3.2.1.jar:na]
at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:130) ~[querydsl-jpa-3.2.1.jar:na]
at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:97) ~[querydsl-jpa-3.2.1.jar:na]
at com.mysema.query.jpa.impl.AbstractJPAQuery.list(AbstractJPAQuery.java:240) ~[querydsl-jpa-3.2.1.jar:na]
...
public List<Person> getEmailStartWith(String pattern) {
    pattern = Email.normalize(pattern);
    return getEntityManager()
        .createQuery("select p from Person p where p.email like concat(?1, '%')", Person.class)
        .setParameter(1, pattern)
        .getResultList();
}

共有1个答案

太叔坚
2023-03-14

根据Querydsl创建者Timo Westkämper的说法,这个问题更多地与EclipseLink相关。

 类似资料:
  • 问题的核心似乎是Eclipselink中没有到类型的内部映射。因此,使用一种简单的方法: ...在尝试插入一个对象时,我遇到了一个异常: 我想很公平。 通过查看EclipseLink文档,似乎适用的定制(转换映射、本机查询、转换器)依赖于由所支持的映射(数字、日期、字符串等)组成的数据,因此使用特定于供应商的类型很难做到这一点。 这是如此令人沮丧的主要原因是,posgresql中的类型与text/

  • 问题内容: 我对SQLITE相当陌生,我注意到只有4种数据类型,但是我在网上看到的例子中人们在放置自己的数据类型。我对此不太了解,想知道是否有人可以向我解释。例如,我看到一列将保存日期,并且给定的数据类型是不存在的时间戳。默认是什么?自己制作时默认为文本吗? 问题答案: 使用动态类型系统。只有五个存储类:NULL,整数,实数,文本和blob。(来源:SQLite版本3中的数据类型。) 并且,引用该

  • 4.4.5 数据类型的自定义 在有了一些数据类型后,程序员还可定义这些数据类型的别名或指针类型。表达这种定义的伪指令是TYPEDEF,其定义形式如下: 新数据类型名 TYPEDEF [位距] [PTR] 数据类型 其中:“位距”是NEAR、FAR或PROC等。 例如: CHAR TYPEDEF BYTE ;给BYTE定义另一个别名CHAR PCHAR TYPEDEF PTR CHAR ;定义一个字

  • 我可以使用自定义字段值获取数据吗?我的是,字段名是。那么,如何使用获取所有数据呢? 代码如下: 此代码不起作用。

  • 我正在尝试为PGInterval和Duration编写一个自定义数据类型绑定,以将jOOQ与TimescaleDB一起使用。遗憾的是,jOOQ在为数据库例程生成函数时没有使用它。 这是我的绑定类: 这是我在pom中的配置: 例如,我希望jOOQ生成例程 像 但是我得到了

  • 本章节中,简述自定义类的创建和使用方法,供参考。 创建自定义类 用户可以定义自己的类,通过继承 ThingJS 内部类(比如:Thing 类),对 ThingJS 进行扩展和封装。 我们推荐使用 ES6 语法定义一个类。例如,自定义汽车类 Car。 // 继承 Thing 类 class Car extends THING.Thing { constructor(app) { super(