我试图构建一个条件查询,并为每个传入的过滤器构建一个谓词“and”连接,例如。
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> criteriaQuery = criteriaBuilder.createQuery(Long.class);
Root<T> entityRoot = criteriaQuery.from(SampleEntity.class);
// for each filterable field create a Predicate and included in as `criteriaQuery.where(...)`
criteriaQuery.select(criteriaBuilder.count(entityRoot));
entityManager.createQuery(criteriaQuery).setMaxResults(maxResult).getSingleResult();
Path<?> path = PathBuilder.buildFromFieldName(fieldName, rootEntity);
public static <T> Path<?> buildFromFieldName(String fieldName, Root<T> entity) throws IllegalArgumentException {
Path<?> path = entity;
List<String> fieldNames = Arrays.asList(fieldName.split("\\."));
for (String fieldNamePath : fieldNames) {
path = path.get(fieldNamePath);
}
return path;
}
在下面的示例中,嵌套字段将出现,例如命名为mychild.myset
。
@Entity
@Table(name = "T_SAMPLE")
public class SampleEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Embedded
private SampleChildEntity myChild;
}
@Embeddable
public class SampleChildEntity {
@Convert(converter = CommaSeparatedSetConverter.class, attributeName = "mySet")
private Set<String> mySet = new HashSet<>();
}
在此示例中,当调用CriteriaBuilder.ismember(filterValue,path)
时,会引发以下异常(“filterValue”是要比较的值,例如搜索字符串)。
原因:在方法buildFromFieldName
中,首先从根实体(SampleEntity)创建路径。然后它的类型为org.hibernate.query.criteria.internal.path.rootimpl
。当在for循环中处理fieldNamePathMyChild
时,将重新创建路径。然后,它的类型为org.hibernate.query.criteria.internal.path.SingularAttributePath
,并且在处理最后一个fieldNamePathMySet
时保持不变。只有当删除@convert
时,类型才会更改为org.hibernate.query.criteria.internal.path.PluralAttributePath
,因为它是集合类型。
java.lang.IllegalArgumentException: unknown collection expression type
[org.hibernate.query.criteria.internal.path.SingularAttributePath]
at org.hibernate.query.criteria.internal.CriteriaBuilderImpl.isMember(CriteriaBuilderImpl.java:1324)
[... stack trace contains further local classes ...]
所以原因是SampleChildEntity
中的@convert
on字段MySet
。Hibernate看到类型set
,但不使用pluralattributePath
,而是使用singularattributePath
,这会导致问题。如果没有@convert
,它就可以工作,但删除转换器不是一个选项。
有什么办法能奏效吗?路径是否可以以不同的方式创建?
通过@convert
使用转换器的持久属性是一个基本属性,因此是SingularAttribute
,所以看到SingularAttributePath
是完全正确的。假设可以对这样一个单数属性使用复数谓词是错误的。Hibernate无法将其转换为SQL,因为它不知道转换器的功能。我猜列代表一个逗号分隔的列表?在这种情况下,您将使用例如like谓词来编写过滤器。类似于这样:
WHERE alias.myChild.mySet = :filterValue
OR alias.myChild.mySet LIKE CONCAT(:filterValue, ';%')
OR alias.myChild.mySet LIKE CONCAT(CONCAT('%;', :filterValue), ';%')
OR alias.myChild.mySet LIKE CONCAT('%;', :filterValue)
将此转换为JPA标准应该很容易。
问题内容: 我有一个名为的表,我想对它们进行排序,以表最填写的顺序。每个列都是JSONB列或TEXT列。我并不需要很确定,因此通常我按以下顺序订购: 但是,这很慢,因此我想创建一个索引。但是,这不起作用: 也没有 不能说我很惊讶。声明此索引的正确方法是什么? 问题答案: 要测量文本表示形式中行的大小,您可以将整个行都转换为文本,这比连接单个列要快得多: 但是索引中的此表达式存在3(或4)个问题:
路径文字是指沿着开放或封闭的路径排列的文字。当您水平输入文本时,字符的排列会与基线平行。当您垂直输入文本时,字符的排列会与基线垂直。无论是哪种情况,文本都会沿路径点添加到路径上的方向来排列 沿路径输入文本 1执行下列操作之一: •要沿路径创建横排文本,请选择文字工具 或路径文字工具 。 •要沿路径创建直排文本,请选择直排文字工具 或直排路径文字工具 。 2(可选)在 “控制 ”面板、 “字符 ”面
问题内容: 这是具有3列(ID,UNIQUE_VALUE,UNIQUE_GROUP_ID)的示例表 我希望下面的记录可以被允许: 或者 或( 注:这种情况是不允许的,也不) 并且这些是不允许的: 我在最后2列上创建了唯一索引,但是仅允许前2个示例。 仅当两者都不为null时,才可以让db检查这两列的唯一性吗? 问题答案: 您只想对和都不为空的行实施唯一性。为此,您可以使用基于函数的唯一索引:
问题内容: 我需要为一个表创建一个timestamp字段,该表的行在一定时间后需要过期。如果我使用以下内容: 它以一种人类可读的格式显示时间,如果我可以将时间设置为纪元时间,则可以轻松得多,这样我就可以用几秒钟的时间进行计算。有没有一种方法可以创建一个字段,当默认情况下以纪元时间创建行时,该字段将显示当前时间?谢谢! 问题答案: 您可能希望在语句中使用该函数,如以下示例所示:
问题内容: 在hibernate状态下使用sqlserver方言。 我希望hibernate在创建表时使用带引号的标识符。 除了重命名字段外,还有其他任何处理方法的想法吗? 问题答案: 遇到相同的问题,但表名为。如果你设定 然后所有数据库标识符将被引用。 在这里找到我的答案 表名称中的特殊字符hibernate给出错误 并在这里找到所有可用的设置 https://docs.jboss.org/hi
路径文字是指沿着开放或封闭的路径排列的文字。当您水平输入文本时,字符的排列会与基线平行。当您垂直输入文本时,字符的排列会与基线垂直。无论是哪种情况,文本都会沿路径点添加到路径上的方向来排列。 在路径上输入文本 执行下列操作之一: 要沿路径创建横排文本,请选择文字工具 或路径文字工具 。 要沿路径创建直排文本,请选择直排文字工具 或直排路径文字工具 。 (可选)在“控制”面板、“字符”面板或“段落”