Skip to content

Instantly share code, notes, and snippets.

@SpOOnman
Last active October 7, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SpOOnman/3175086 to your computer and use it in GitHub Desktop.
Save SpOOnman/3175086 to your computer and use it in GitHub Desktop.
Hibernate Envers with Grails 2.1.0
plugins {
// add this if you've packaged a plugin by yourself
runtime ":envers:0.3-SNAPSHOT"
// add this if you want to use plugin from Grails central repository
runtime ":envers:2.1.0"
}
$ git clone git://github.com/mfolnovic/grails-envers-plugin.git
$ cd grails-envers-plugin
$ grails package-plugin
| Plugin packaged grails-envers-0.3-SNAPSHOT.zip
$ cp grails-envers-0.3-SNAPSHOT.zip ../enversdemo/lib/envers-0.3-SNAPSHOT.zip
import org.hibernate.envers.Audited
@Audited
class Hotel {
String name
static hasMany = [bookings: Booking]
}
@Audited
class Booking {
String surname
Date startDate
Integer daysCount
static belongsTo = [hotel: Hotel]
}
import org.hibernate.envers.Audited
@Audited
class Hotel {
String name
static hasMany = [bookings: Booking]
}
@Audited
class Booking {
String surname
Date startDate
Integer daysCount
static belongsTo = [hotel: Hotel]
}
import grails.plugin.spock.IntegrationSpec
import org.hibernate.SessionFactory
class HotelIntegrationSpec extends IntegrationSpec {
// http://grails.org/doc/latest/guide/testing.html#integrationTesting
// Don't wrap into database transaction that is rolled back at the end.
// Explicitly persist entites in database, I will cleanup, I promise.
static transactional = false
SessionFactory sessionFactory
def cleanup() {
['booking', 'booking_aud', 'hotel', 'hotel_aud', 'user_revision_entity'].each {
sessionFactory.currentSession.createSQLQuery("delete from $it").executeUpdate()
}
}
def "Hotel should be audited with Envers"() {
given:
def hotel = new Hotel(name: "Marriott")
when:
Hotel.withTransaction {
hotel.save(failOnError: true, flush: true)
}
then:
Hotel.count() == 1
Hotel.findAllRevisionsById(hotel.id).size() == 1
UserRevisionEntity.count() == 1
}
}
$ cat ~/.grails/settings.groovy
grails.project.repos.companyNexusSnapshots.url="http://nexus.company.com/nexus/content/repositories/snapshots"
grails.project.repos.companyNexusSnapshots.type="maven"
grails.project.repos.companyNexusSnapshots.username="username"
grails.project.repos.companyNexusSnapshots.password="password"
$ grails publish-plugin --repository=companyNexusSnapshots
| Packaging Grails application.....
[...snip...]
| Plugin packaged grails-envers-0.3-SNAPSHOT.zip
| POM generated: /home/tkl/dev/grails-envers-plugin/target/pom.xml
WARN: No SCM provider installed.
Publishing to Maven repository 'toukNexusSnapshots'
Using configured username and password from grails.project.repos.toukNexusSnapshots
| POM generated: /home/tkl/dev/grails-envers-plugin/target/pom.xml....
No default portal defined for repository 'toukNexusSnapshots' - skipping portal notification
beans = {
System.setProperty('org.hibernate.envers.audit_table_prefix', 'AUDITED_')
System.setProperty('org.hibernate.envers.audit_table_suffix', '')
}
class SpringSecurityRevisionListener implements RevisionListener {
public void newRevision(Object entity) {
UserRevisionEntity revisionEntity = (UserRevisionEntity) entity
User user = SpringSecurityServiceHolder.springSecurityService?.currentUser
revisionEntity.currentUser = user
}
}
@RevisionEntity(SpringSecurityRevisionListener.class)
class UserRevisionEntity {
@RevisionNumber
Long id
@RevisionTimestamp
Long timestamp
User currentUser
static constraints = {
currentUser(nullable: true)
}
static transients = ['revisionDate']
public Date getRevisionDate() {
return new Date(timestamp);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment