我在我的Java项目中使用带有Spring Data JPA的QueryDSL,并使用QueryDSL maven插件生成文件,以使用它生成的QueryDSL Model类.当我将它用于一个级别的嵌套对象时,这非常有用,但是如果我尝试访问第二级访问对象,则会产生NullPointerException,从而无法初始化第二级模型对象.
会感激一些帮助.
我在第3行获得NullPointerException qmachine.vendor为null.
QTransaction qtransaction = QTransaction.transaction;
QMachine qmachine = qtransaction.machine;
BooleanExpression vendorexp = qmachine.vendor.vendor.eq(machineType);
Run Code Online (Sandbox Code Playgroud)
我的映射类如下:交易
@Entity
@Table(name = "dsdsd")
public class Transaction extends AbstractPersistable<Long> {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "machine_id")
private Machine machine;
}
Run Code Online (Sandbox Code Playgroud)
机器类是:
@Entity
@Table(name="machine")
public class Machine extends AbstractPersistable<Long> {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name="vendor_id")
private Vendor vendor;
}
Run Code Online (Sandbox Code Playgroud)
和供应商类是
@Entity
@Table(name="vendors")
public class Vendor extends AbstractPersistable<Long> {
private static final …Run Code Online (Sandbox Code Playgroud) 我试过阅读QueryDSL文档,但我仍然很困惑.我习惯于编写很多SQL,但这是我第一次使用带有JPQL(JPA2)的QueryDSL.
我有以下实体:
@Entity
public class Provider implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
@Version
@Column(name = "version")
private Integer version;
private String name;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "provider_contact", joinColumns = @JoinColumn(name = "contact_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "provider_id", referencedColumnName = "id"))
@OrderColumn
private Collection<Contact> contact;
}
Run Code Online (Sandbox Code Playgroud)
其中Contact是一个带有idpk 的简单实体.
@Entity
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
/**
* User first name
*/
@NotNull …Run Code Online (Sandbox Code Playgroud) 我使用的是QueryDsl,所以我的源码依赖于生成的代码.
第一
每当IDEA(auto)导入pom.xml时,以下设置始终为空:
构建,执行,部署 - >编译器 - >注释处理器 - >注释处理器
我必须手动设置它,这非常麻烦.
第二
我有使用QueryDsl的多模块,我希望将其分组到com.mysema.query.apt.jpa.JPAAnnotationProcessor应用了QueryDsl的一个配置文件中.
构建,执行,部署 - >编译器 - >注释处理器 - >配置文件
我目前必须手动将这些模块分组到一个配置文件中.
我还必须编写自述文件并通知所有成员按照指南手动设置IDEA.
如何配置pom.xml,以便IDEA可以自动填充这两个设置?
我已经创建了一个自定义数据类型来存储有效和规范化的电子邮件地址:
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);
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
其对应的JPA 2.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);
}
} …Run Code Online (Sandbox Code Playgroud) 我一直在寻找文档的一些时间,并尝试了几件事,但我无法动态添加querydsl的where子句:
伪代码,我需要像"if"这样的东西:
boolean addWhereClause = false;
QAddress address = QAddress.address;
JPQLQuery query = new JPAQuery(getEntityManager());
query.from(address)
.if(addWhereClause).where(address.company.isNotNull())
Run Code Online (Sandbox Code Playgroud)
或者更好的地方如果:
boolean addWhereClause = false;
QAddress address = QAddress.address;
JPQLQuery query = new JPAQuery(getEntityManager());
query.from(address)
.whereIf(addWhereClause, address.company.isNotNull())
Run Code Online (Sandbox Code Playgroud)
到目前为止我唯一发现的是使用BooleanBuilder,但我认为有更好的方法(比如上面的伪代码).
亲切的问候,土工
使用Spring Data nad Querydsl,我们可以声明存储库接口并跳过实现类.一些具有特定名称或使用@Query注释的方法,这就是全部.
但是有时候我想使用JPAQuery并自己定义方法的主体,比方说
@Repository
public class MyRepositoryImpl implements MyRepository {
@PersistenceContext
private EntityManager em;
@Override
public List<Tuple> someMethod(String arg) {
JPAQuery query = new JPAQuery(em);
...
}
Run Code Online (Sandbox Code Playgroud)
但这样我就必须实现其他MyRepository接口方法,这会破坏Spring Data的所有优点!
我可以看到两个选项:
我更喜欢选项#2,但据我所知,在@Service类中我们应该只调用存储库方法,所以它也不是一个完美的解决方案.
那么程序员如何处理呢?
我使用的是spring-data,QueryDSL和MySQL.
问题的主要目的是知道如何以queryDSL方式进行这样的查询.给出的例子只是一个提供想法的简单例子.
比如说,有两个表Employee和Certificate.两者之间的关系是ONE(员工)到MANY(证书)
以下是表格,
Employee (id, first_name, last_name);
Certificate (id, name, date, fk_emp);
Run Code Online (Sandbox Code Playgroud)
QueryDSL谓词应该是什么
返回名称中包含的所有员工(在first_name和last_name中)以及从日期为22-12-2014到22-12-2015之间的认证结果
我尝试了但是无法获得如何以QueryDSL方式迭代每个员工的每个证书并返回员工列表.
您的回复将受到高度赞赏!
编辑
以下是实体,
@Entity
@Table(name = "EMPLOYEE")
class Employee {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL)
private List<Certificate> certificates = new ArrayList<>();
}
@Entity
@Table(name = "CERTIFICATE")
class Certificate {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = …Run Code Online (Sandbox Code Playgroud) Spring Boot REST服务和MySQL在这里.我有以下Profile实体:
@Entity
@Table(name = "profiles")
public class Profile extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "profile_given_name")
private String givenName;
@Column(name = "profile_surname")
private String surname;
@Column(name = "profile_is_male")
private Integer isMale;
@Column(name = "profile_height_meters", columnDefinition = "DOUBLE")
private BigDecimal heightMeters;
@Column(name = "profile_weight_kilos", columnDefinition = "DOUBLE")
private BigDecimal weightKilos;
@Column(name = "profile_dob")
private Date dob;
// Getters, setters & ctor down here
}
Run Code Online (Sandbox Code Playgroud)
我也有一个ProfileController,我希望公开一个GET端点,它提供了一种非常灵活/强大的搜索方式,可以 …
要求
例如,resourceA.attribute1 =“ CAT” AND resourceA.subResourceB.attribute2> = 42 AND resourceA.attribute3 IN(“ WHIZ”,“ BANG”)
我研究了四种解决方案-每种解决方案都更加接近目标。有没有我找不到的其他解决方案,还是没有这样的完整解决方案-是在下面概述的“基于RSQL的REST查询语言”基础上的答案吗?
1)春季数据剩余查询
Spring数据中有很多支持,可用于在代码中开发复杂的查询,但这要求开发人员事先了解查询的结构,并相应地构造代码。 https://docs.spring.io/spring-data/rest/docs/current/reference/html/#repository-resources.query-method-resource
2)spring-data,spring-data-rest,query-dsl
http://www.baeldung.com/rest-api-search-querydsl-web-in-spring-data-jpa
+ ve非常适合-完全可用的解决方案,开箱即用几乎为零
可以构建+ ve深度嵌套的查询,并且服务器可以动态生成正确的SQL。
-ve唯一的运算符是EQUALS'=',以便应用其他运算符,您需要实现QuerydslBinderCustomizer实例,这再次要求服务器代码提前知道查询的复杂性。
3)Baeldung-“建立休息查询语言”
http://www.baeldung.com/spring-rest-api-query-search-language-tutorial
+ ve-接近通用查询语言
-ve-感觉像是演示/ POC
4)使用RSQL的REST查询语言
http://www.baeldung.com/rest-api-search-language-rsql-fiql
+ ve-感觉更完整的查询语言和相关的解析器
-ve-不确定弹簧集成
我有两对的三个整数值。
我想将其用作 WHERE 子句中的 IN 列表。
(2019, 5) (2019, 6) (2019, 7)
我想在这样的查询中使用上面的两对列表:
SELECT
*
FROM
WEEK_REPORT A
WHERE
A.user_id IN ('test2','test5' ) AND
(A.year, A.week_no) IN ((2019,4),(2019,5),(2019,6));
Run Code Online (Sandbox Code Playgroud)
为此,我写了如下源代码:
// lastYear=2019, lastWeekNo=4
Tuple t = JPAExpressions.select(Expressions.constant(lastYear), Expressions.constant(lastWeekNo))
.from(weekReport)
.fetchOne();
// currentYear=2019, currentWeekNo=5
Tuple t2 = JPAExpressions.select(Expressions.constant(currentYear), Expressions.constant(currentWeekNo))
.from(weekReport)
.fetchOne();
// nextYear=2019, nextWeekNo=4
Tuple t3 = JPAExpressions.select(Expressions.constant(nextYear), Expressions.constant(nextWeekNo))
.from(weekReport)
.fetchOne();
return queryFactory
.select(weekReport)
.from(weekReport)
.where(weekReport.user.eq(user)
.and(Expressions.list(weekReport.year, weekReport.weekNo).in(t, t2, t3)))
.fetch();
Run Code Online (Sandbox Code Playgroud)
但是,不会输出正确的结果并发生错误。
java.lang.UnsupportedOperationException: null
at com.querydsl.jpa.JPASubQuery.fetchOne(JPASubQuery.java:66) ~[querydsl-jpa-4.1.4.jar:na]
Run Code Online (Sandbox Code Playgroud)
我在官方文档里查了一下,没有出来。
有办法吗?
谢谢你。
querydsl ×10
java ×4
spring-data ×4
spring ×3
jpa ×2
jpql ×2
mysql ×2
eclipselink ×1
in-clause ×1
spring-boot ×1
sql ×1