简体   繁体   English

对可能为null或不为null的属性应用限制

[英]Applying Restrictions on an attribute that may or may not be null

Below is the class definition for Listener class which is also a database entity. 以下是侦听器类的类定义,该类也是数据库实体。 It has a relationship with TLS entity. 它与TLS实体有关系。

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "LISTENER")
@IdClass(EntityId.class)

public class Listener implements MultitenantEntity, AuditedEntity {

    @Id
    @Column(name = "LISTENER_ID")
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    public String id;

    @Id
    @Column(name = "LISTENER_INSTANCE_ID")
    private String instanceId;

    @OneToMany(mappedBy="listener", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @Fetch(value= FetchMode.SELECT)
    private List<Path> paths;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns ({
        @JoinColumn(name="TLS_NAME"),
        @JoinColumn(name="INSTANCE_ID")
    })
    @Fetch(value=FetchMode.SELECT)
    private TlsDescriptor tlsDescriptor;

    @Embedded
    @Builder.Default private AuditMetadata audit = new AuditMetadata();
}

Below is the class definition for TLS, which is also a database entity: 以下是TLS的类定义,它也是一个数据库实体:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "TLS_DESCRIPTOR")
@IdClass(EntityId.class)
public class TlsDescriptor implements MultitenantEntity, AuditedEntity        {
    @Id
    @Column(name = "TLS_NAME")
    public String id;

    @Id
    @Column(name = "INSTANCE_ID")
    private String instanceId;

    @Column(name = "TLS_PROTOCOL")
    public String tlsProtocol;

    @Column(name = "CIPHERS")
    public String ciphers;

    @Lob
    @Column(name = "CERTIFICATE", nullable = false)
    public String certificate;

    @Lob
    @Column(name = "PRIVATE_KEY", nullable = false)
    public String privateKey;

    @Embedded
    @Builder.Default private AuditMetadata audit = new AuditMetadata();
}

Here, AuditMetadata is a class which contains attributes such as createdTimestamp and modifiedTimestamp, essentially keeping track of the created time and modified time of the object it is associated with. 在这里,AuditMetadata是一个类,其中包含诸如createdTimestamp和ModifyedTimestamp之类的属性,本质上跟踪与之关联的对象的创建时间和修改时间。

Now, I wrote the below Hibernate query which tries to fetch the listener objects for which: 现在,我编写了下面的Hibernate查询,该查询尝试为其获取侦听器对象:

  1. Either the listener itself was updated after the time mentioned in the 'timestamp' elapsed 在“时间戳记”中提到的时间过去之后,要么更新侦听器本身

  2. Or the associated path was updated after the time mentioned in the 'timestamp' elapsed 或者在“时间戳记”中提到的时间过去之后,相关路径已更新

  3. Or the associated tlsDescriptor was updated after the time mentioned in the 'timestamp' elapsed 或者相关的tlsDescriptor在“时间戳记”中提到的时间过去之后已更新

      public List<Listener> findAll(long timestamp, long now, Pageable pageable) { return super.find(currentSession() .createCriteria(Listener.class, "listener") .createAlias("listener.paths", "path") .add(Restrictions.or( Restrictions.between("audit.modifyTimestamp", new Date(timestamp), new Date(now)), Restrictions.between("path.audit.modifyTimestamp", new Date(timestamp), new Date(now)), Restrictions.between("listener.tlsDescriptor.audit.modifyTimestamp", new Date(timestamp), new Date(now)))) .add(Restrictions.isNotEmpty("listener.paths")), pageable); 

    } }

Now the problem is, path is a mandatory field but tlsDescriptor is an optional field. 现在的问题是,path是必填字段,而tlsDescriptor是可选字段。 So the query works fine when tlsDescriptor is present, but if it is absent, then I get the following error: 因此,当存在tlsDescriptor时,该查询工作正常,但如果不存在,则会出现以下错误:

org.hibernate.QueryException: could not resolve property: tlsDescriptor.audit.modifyTimestamp of:Listener

I tried trying to resolve this using conjunction, disjunction, AND and OR statements of Hibernate, but this error keeps repeating! 我试图尝试使用Hibernate的合取,析取,AND和OR语句解决此问题,但此错误不断重复!

Use alias for tlsDescriptor with JoinType.LEFT_OUTER_JOIN (so result will not be empty if related model is null): 对带有JoinType.LEFT_OUTER_JOIN的tlsDescriptor使用别名(因此,如果相关模型为null,则结果不会为空):

public List<Listener> findAll(long timestamp, long now, Pageable pageable) {
return super.find(currentSession()
                .createCriteria(Listener.class, "listener")
                .createAlias("listener.paths", "path")
                .createAlias("listener.tlsDescriptor", "tls", JoinType.LEFT_OUTER_JOIN)
                .add(Restrictions.or(
                        Restrictions.between("audit.modifyTimestamp", new Date(timestamp), new Date(now)),
                        Restrictions.between("path.audit.modifyTimestamp", new Date(timestamp), new Date(now)),
                        Restrictions.between("tls.audit.modifyTimestamp", new Date(timestamp), new Date(now)))),
        pageable);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM