Search code examples
javahibernatequarkusquarkus-panachequarkus-hibernate-orm

Accessing schema name in filter condition


@Entity
@Table(name = "my_table")
@FilterDef(name = "MyTable.current")
@Filter(name = "MyTable.current", condition = """
    revision_number = (select max(v.revision_number) from {h-schema}my_table as v where id = v.id)
            """)
public class MyRevisioneEntity extends PanacheEntityBase {
  @Id
  /* This is NOT autogenerated */
  UUID id;
  @Id
  @Column(name = "revision_number")
  long revision;
  @Basic(fetch = FetchType.LAZY)
  @Formula("(revision_number = (select max(v.revision_number) from {h-schema}my_table as v where id = v.id))")
  boolean latestRevision;
  // ... metadata, target of revision!
}

Above my domain,a simple entity identified by an UUID, can have multiple revisions.
Normally I need only most recent revision so I decided to create a filter MyTable.current but I have a problem, the {h-schema} placeholder is not resolved so I have to forge schema in filter condition.
The same condition applied as @Formula to property latestRevision works flawlessy (placeholder is resolved as expected).

Is this by design or @Filter condition should resolve placeholder as @Formula does?


Solution

  • I don't think {h-schema} is supported here... Though maybe it should be; feel free to create a feature request: https://hibernate.atlassian.net/browse/HHH

    In the meantime, you could try simply using @SqlFragmentAlias:

    @Filter(name = "MyTable.current", condition = """
        revision_number = (select max(v.revision_number) from {mytable} as v where id = v.id)
                """,
        aliases = @SqlFragmentAlias(alias = "mytable", table = "my_table"))
    public class MyRevisioneEntity extends PanacheEntityBase {
    

    See also https://docs.jboss.org/hibernate/orm/6.5/userguide/html_single/Hibernate_User_Guide.html#pc-filter-sql-fragment-alias.

    BTW, you might want to consider using Envers instead of rolling out your own solution.


    EDIT: the suggestion below doesn't work, see https://hibernate.atlassian.net/browse/HHH-18152

    @Filter(name = "MyTable.current", condition = """
        revision_number = (select max(v.revision_number) from {mytable} as v where id = v.id)
                """,
        aliases = @SqlFragmentAlias(alias = "mytable", entity = MyRevisioneEntity.class))
    public class MyRevisioneEntity extends PanacheEntityBase {
    

    See also https://docs.jboss.org/hibernate/orm/6.5/userguide/html_single/Hibernate_User_Guide.html#pc-filter-sql-fragment-alias (though that section doesn't seem to mention entity =, so perhaps it's outdated).