-
Notifications
You must be signed in to change notification settings - Fork 8
Home
Integrates Hibernate filtering into Grails 3 with Hibernate 5 and GORM 6
This plugin allows Hibernate filters to be used in a GORM domain model.
Please check the gradle file to determine the most recent release, because the version displayed on this page is unreliable.
The plugin allows you to easily define hibernate filters on classes and associations within the domain class. Filters can be disabled/enabled anywhere within the code. Filters can also be designated as a default filter to be automatically applied. This allows smart defaults for security purposes.
This is very useful to enforce security rules outside of the GORM methods. Filters can also be applied to collections so that views don't have to enforce security without the use of DTOs.
Add dependency in build.gradle:
repositories {
maven { url "https://dl.bintray.com/goodstartgenetics/grails3-plugins/" }
}
dependencies {
compile "org.grails.plugins:hibernate-filter-plugin:0.5.4"
}
Hibernate filters are configured in domain classes (grails-app/domain):
class Member {
boolean enabled
boolean visible
static hasMany = [images: Image, pens: Pen]
static hibernateFilters = {
enabledFilter(condition:'enabled=1', default: true)
validFilter(condition:'enabled=1 and visible=1', aliasDomain:'ValidMember')
enabledFilter(collection:'images', default: true)
yearParam(condition: ':myParam = year', types: 'string')
pensFilter(collection: 'pens', joinTable: true)
}
}
- The first line creates a default filter called 'enabledFilter' which the condition 'enabled=1'
- The second line creates a non-default filter called 'validFilter' with an alias domain 'ValidMember'
- The third line creates a default filter that uses the same condition as the first one and applies it to the association 'images'
Filters with the same name use the same condition even if not in the same domain class
Filters are not applied to
Domain.get()
because.get()
is not considered a query. If filters should be applied when loading an object by ID, useDomain.findById()
instead
- condition - The filter condition
- default - true to enable this filter by default (or a closure returning true or false)
- collection - the collection (association) to apply this filter to
- aliasDomain - A domain name to use when you want to apply this filter in a single instruction.
Example: ValidMember.findAllByName('user1')
- Will find only members matching the validFilter with the name 'user1'
Since version 0.4.0, you are required to indicate any filtered associations that are mapped via a join table with joinTable: true
In the example above, joinTable: true
is specified for the pens
collection, but not the images
collection, because only the former is mapped via a join table. Additional examples are available in the test cases.
Several methods are injected into grails domain classes
withHibernateFilter - execute the enclosed code with the named filter enabled
Foo.withHibernateFilter('filterName') {
..code to execute
}
withHibernateFilters - execute the enclosed code with all default filters enabled
Foo.withHibernateFilters {
..code to execute
}
withoutHibernateFilter - execute the enclosed code with the named filter disabled
Foo.withHibernateFilter {
..code to execute
}
withoutHibernateFilters - execute the enclosed code with all default filters disabled
Foo.withoutHibernateFilters {
..code to execute
}
enableHibernateFilter - enable a Hibernate filter (returns the Hibernate org.hibernate.Filter
instance)
Foo.enableHibernateFilter('filterName')
def filter = Foo.enableHibernateFilter('filterWithArgs')
filter.setParameter('argName', 42)
disableHibernateFilter - disable a hibernate filter
Foo.disableHibernateFilter('filterName')
Book.enableHibernateFilter('yearParam').setParameter('myParam', '2008')
Enables the 'yearParam' filter and sets the parameter to '2008'.
Given the above domain configuration
Data
- Member (name:'user1', enabled:true)
- Image (name:'image1', enabled:false)
- Image (name:'image2', enabled:true)
- Image (name:'image3', enabled:true)
- Member (name:'user2', enabled:false)
- Member (name:'user3', enabled:true, visible:true)
Controller
class MemberController {
def sessionFactory
def index = {
Member.withoutHibernateFilter('enabledFilter') {
println Member.list() // returns all members
}
// renders a view with members and images where enabled=true
[members: Member.list()]
}
}
View
<body>
<g:each in="${members}" var="member">
member: ${member.name} (enabled:${member.enabled})
<g:each in="${member.images}" var="image">
image: ${image.name} (enabled:${image.enabled})
</g:each>
<br/>
</g:each>
</body>
OUTPUT
member: user1 (enabled:true)
image: image2 (enabled:true)
image: image3 (enabled:true)
member: user3 (enabled:true)