GEDOPLAN

Globale Entity-Filter mit Hibernate @Filter

Alle
coffee gee8e882c6 640 1
coffee gee8e882c6 640 1

Dank JPQL oder der Criteria API sind Queries keine große Sache. Doch oft entsteht in Projekten die Anforderung, Daten basierend auf z.B. Berechtigungen zu filtern. Alle Abfragen mit entsprechenden where-Clauseln zu versehen mag pragmatisch sein, ist aber sehr anfällig für Fehler und die Wartbarkeit leidet.

Hibernate bietet für genauso diesen Zweck @Filter Annotation an, die es uns erlauben auf Entity-Ebene Filter zu deklarieren, die bei Bedarf aktiviert werden können. Die Definition solcher Filter geschieht per Annotation auf z.B. der Entity selbst oder aber auch auf Package Ebene:

@FilterDefs(
        @FilterDef(
                name = FilterNames.BY_MATERIAL_NUMBER,
                parameters = @ParamDef(name = FilterNames.BY_MATERIAL_NUMBER_P_PREFIX, type = "string"),
                defaultCondition = "material_number like :" + FilterNames.BY_MATERIAL_NUMBER_P_PREFIX
        )
)

Unser Filter definiert einen Namen (der später dazu verwendet, wird die, Aktivierung durchzuführen), ein oder mehrere Parameter und natürlich die konkrete SQL Kondition.

Dieser Filter muss nun lediglich auf Entity-Ebene durch eine entsprechende Annotation konfiguriert werden

@Entity
@Filter(name = FilterNames.BY_MATERIAL_NUMBER)
public class Material {...}

Solche Filter sind per Default deaktiviert und müssen nun für die aktive Hibernate Session aktiviert werden. Dies lässt sich über den Entitymanager ganz leicht durchführen

Session session = em.unwrap(Session.class);
Filter filter = session.enableFilter(FilterNames.BY_MATERIAL_NUMBER);
filter.setParameter(FilterNames.BY_MATERIAL_NUMBER_P_PREFIX, "99%");

em.createQuery(...)

In der laufenden Session werden jetzt alle Queries, die direkt „Material“ adressieren, zusätzlich mit unserem Filter versehen. Wichtig: das betrifft lediglich alle Filter Queries, ein direktes Laden über die Id mittels z.B. „load“ führt keine Filterung durch und auch das Laden abhängiger Entities (OneToMany, ManyToMany) bedarf zusätzlicher Annotationen (@FilterJoinTable).

Filter by Default

Oft wollen wir solche Filter immer aktivieren, um z.B. über die Berechtigungen des Users Einschränkungen durchzuführen. In Spring Boot bietet sich dafür eine Customizer Methode an

@Configuration
public class MaterialFilter {
    @Bean
    @ConditionalOnMissingBean
    public PlatformTransactionManager transactionManager(
            ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
        JpaTransactionManager transactionManager = new JpaTransactionManager() {
            @Override
            protected EntityManager createEntityManagerForTransaction() {
                final EntityManager entityManager = super.createEntityManagerForTransaction();
                Session session = entityManager.unwrap(Session.class);
                activateMaterialFilterByRole(session); // read roles, activate filter, set parameters
                return entityManager;
            }
        };
        transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
        return transactionManager;
    }

(als Alternative wäre auch eine Lösung mittels AOP Methoden möglich)

Und wie immer hier noch mal alles Live und in Farbe: https://github.com/GEDOPLAN/hibernate-filter

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Schulungen mit der selben Kategorie:

Blogkategorie: Alle
Es wurden keine Ergebnisse gefunden.

weitere Artikel

Kontakt

Brauchen Sie eine individuelle IT-Schulung, eine fundierte Beratung oder eine individuelle Softwareentwicklung? Dann sind Sie hier genau richtig!

Tim Neumann

Geschäftsleitung

GEDOPLAN GmbH
Stieghorster Straße 60
33605 Bielefeld

GEDOPLAN GmbH
Kantstraße 164
10623 Berlin

    Kontakt

    Tim Neumann

    Geschäftsleitung

    GEDOPLAN GmbH
    Stieghorster Straße 60
    33605 Bielefeld

    GEDOPLAN GmbH
    Kantstraße 164
    10623 Berlin

    Brauchen Sie eine individuelle IT-Schulung, eine fundierte Beratung oder eine individuelle Softwareentwicklung? Dann sind Sie hier genau richtig!