我有一个实体,它包含与少数实体的多态关联。它定义:
@Entity
@Table(name = "notifications")
public class Notification implements java.io.Serializable {
//some fields ...
//Polymorphic association
@Any (metaColumn = @Column(name = "target_type"), fetch = FetchType.LAZY)
@AnyMetaDef(idType = "integer", metaType = "string",
metaValues = {
@MetaValue(targetEntity = Task.class, value = "Task"),
@MetaValue(targetEntity = AdminNote.class, value = "AdminNote"),
@MetaValue(targetEntity = UserCancelRequest.class, value = "UserCancelRequest"),
//@MetaValue(targetEntity = TransferInfo.class, value = "TransferInfo"),
//@MetaValue(targetEntity = NoteSubscription.class, value = "NoteSubscription")
})
@JoinColumn(name = "target_id")
@Getter
@Setter
private NotificationAssociation target;
我的多态关联由接口NotificationAssociation表示:
public interface NotificationAssociation {
/**
* Return actual type of associated entity
* @return one of {@link NotificationTargetType}
*/
String getTargetType();
/**
* Return associated entity id. Used in queries
* @return target entity id
*/
Integer getTargetId();
}
这很有效。但我需要通过静态元模型API从条件中的 Notification 类访问目标。我的元模型:
@StaticMetamodel(Notification.class)
public class Notification_ {
public static volatile SingularAttribute<Notification, Integer> id;
public static volatile SingularAttribute<Notification, Integer> postedById;
public static volatile SingularAttribute<Notification, Integer> adminId;
public static volatile SingularAttribute<Notification, NotificationAssociation> target;
public static volatile SingularAttribute<Notification, Date> hiddenAt;
public static volatile SingularAttribute<Notification, Date> createdAt;
}
在HQL / JPQL中我可以访问它, 但是在元模型 target 中为null,当我通过Root#getModel()获取模型时, target 不会出现在属性列表中。 我的问题是我可以这样做还是有任何其他解决方案。谢谢你的帮助
答案 0 :(得分:1)
我很确定您已经解决了您的问题,但是我最近也遇到了同样的问题。 就我而言,我确实需要使用CriteriaAPI,因为我已经进行了一些用于创建规范的通用处理。 由于HQL不是我的选择,因此我们无法将HQL与规格混合使用。 我通过两次映射该列来解决此问题。以您的示例为例:
@Any (metaColumn = @Column(name = "target_type"), fetch = FetchType.LAZY)
@AnyMetaDef(idType = "integer", metaType = "string",
metaValues = {
@MetaValue(targetEntity = Task.class, value = "Task"),
@MetaValue(targetEntity = AdminNote.class, value = "AdminNote"),
@MetaValue(targetEntity = UserCancelRequest.class, value = "UserCancelRequest")
})
@JoinColumn(name = "target_id")
@Getter
@Setter
private NotificationAssociation target;
@Column(name = "target_id", insertable = false, updatable = false)
private Integer targetId;
进行一些小的调整,就为targetId字段生成了元数据,并且该元数据在Criteria API上可用。因此,您可以执行以下操作:
notificationService.getAll((root, query, cb) -> cb.and(cb.equals(root.get("targetId"), someId), ...))
我希望这对面临相同问题的所有人有所帮助。
答案 1 :(得分:0)
想想我弄明白了。 @Any注释与它相关(@AnyMetadef和其他)由Hibernate提供,而不是JPA。因此,我们无法使用JPA Criteria API来管理此类关系,但我们可以使用Hibernate Criteria API。