9

I am trying to mane hibernate OneToOne relationships work lazily.

My setup is spring-data-jpa using hibernate and Gradle.

Even this is a well-documented problem/feature and there is a lot of good reads out there, I have come to realise that most of them are dealing with maven.

Fortunately, there is a Gradle plugin that can be used for this particular reason and even though the documentation is not the best, I have found this post that also deals with the same issue and it seems like a pretty straightforward solution.

After I implemented the changes needed in my Gradle script, it seemed like hibernate still loads the OneToOne relationships eagerly, so I tried to perform

./gradlew build

and noticed that the following message is printed:

Skipping Hibernate bytecode enhancement since no feature is enabled

according to the source code of the plugin, this message is shown when the enhancement is not enabled, which is not the case as I am using:

hibernate {
enhance {
    enableLazyInitialization= true
    enableDirtyTracking = true
    enableAssociationManagement = true
    enableExtendedEnhancement = true
}}

So my question is has anyone got this to work properly? If yes can you please point me to some tutorial/guide in order to achieve it? I am using an interceptor in an integration test to verify the number of queries hibernate is using as well as monitoring the sql logs.

My gradle file looks like:

buildscript {
repositories { mavenCentral() }
dependencies {
   classpath 'com.github.ben-manes:gradle-versions-plugin:+'
}
dependencies {
    classpath "org.hibernate:hibernate-gradle-plugin:5.2.15.Final"
 }
}

plugins {
 id "io.spring.dependency-management" version "1.0.3.RELEASE"
}

ext { springBootVersion = '1.5.4.RELEASE' }
ext['flyway.version'] = '4.0.3'

apply plugin: 'java'
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'org.hibernate.orm'


hibernate.enhance {
  enableLazyInitialization = true
  enableDirtyTracking = true
  enableAssociationManagement = true
  enableExtendedEnhancement = true
}

jar {
  baseName = 'domain'
  version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8

repositories { mavenCentral() }


configurations.all {
 exclude module: 'logback-classic'
}

dependencies {
  compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.15.Final'
  compile group: 'org.springframework', name: 'spring-jdbc', version: '4.3.9.RELEASE'
  compile('org.springframework.boot:spring-boot-starter')
  compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
  compile group: 'com.zaxxer', name: 'HikariCP', version: '2.6.3'
  compile group: 'org.flywaydb', name: 'flyway-core', version: '4.0.3'
  compile group: 'org.postgresql', name: 'postgresql', version: '42.1.1'
  compile 'com.github.ulisesbocchio:jasypt-spring-boot-starter:1.12'
  compile group: 'org.hibernate', name: 'hibernate-validator', version: '5.2.4.Final'
  compileOnly 'org.projectlombok:lombok:1.16.20'
  testCompile('org.springframework.boot:spring-boot-starter-test')
  testCompile 'org.hsqldb:hsqldb:2.3.3'
  testCompile group: 'org.glassfish.web', name: 'el-impl', version: '2.2.1-b05'
  compileOnly 'com.google.code.findbugs:annotations:3.0.1'
}

dependencyManagement {
  imports { mavenBom("org.springframework.boot:spring-boot- 
  dependencies:${springBootVersion}") }
}

checkstyle {
   configFile = file("../checks.xml")
   toolVersion = '7.5.1'
}

tasks.withType(FindBugs) {
  ignoreFailures true
  effort 'min'
  reportLevel 'high' // low, medium, high
  reports {
     xml {
         enabled true
     }
      html.enabled false
   }
 }

sourceSets {
    integrationTest {
     java {
         compileClasspath += main.output + test.output
         runtimeClasspath += main.output + test.output
         srcDir file('src/integration_test/java')
     }
     resources.srcDir file('src/integration_test/resources')
   }
}

task integrationTest(type: Test) {
   testClassesDir = sourceSets.integrationTest.output.classesDir
   classpath = sourceSets.integrationTest.runtimeClasspath
   outputs.upToDateWhen { false }
}

configurations {
   integrationTestCompile.extendsFrom testCompile
   integrationTestRuntime.extendsFrom testRuntime
}
maxsap
  • 2,771
  • 9
  • 40
  • 69
  • I thought @ OneToOne support fetch=LAZY? Why do you need bytecode enhancement etc ? docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/… Which Hibernate version are you using? Also does your @ OneToOne association has constraints (e.g. not nullable) ? – hovanessyan Mar 14 '18 at 10:32
  • This is an optional inverse one to one relation, I am using spring boot 1.5.4 which comes with hibernate 5.0.12. In these cases fetch Lazy is just ignored from hibernate – maxsap Mar 14 '18 at 11:38
  • Do you have all the sections as described in the official doc (Example 5)? https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/pc/BytecodeEnhancement.html – hovanessyan Mar 14 '18 at 12:06
  • Which version of the gradle plugin are you using? – hovanessyan Mar 14 '18 at 12:18
  • @hovanessyan Sorry for the late response, yes, I am following the official doc, my gradle version is 3.2.1 – maxsap Apr 09 '18 at 08:51
  • @maxsap could you post your build.gradle or at least more of the relevant code? Where do you apply the plugin and where do you configure the extension, are any of those call nested in anything? – wasyl May 19 '18 at 17:10
  • I guess an answer for your problem is either you don't need to use any byte code enhancement at all, or your use case is impossible to do because the nature of RDBMS works. If you could post minimum use case to github about what you're trying to do, maybe me or someone else could help you better. – xsalefter May 20 '18 at 19:40
  • I have same issue and you may define `apply plugin: 'org.hibernate.orm'` on the top of `apply plugin: 'org.springframework.boot'` below definition did not work. apply plugin: 'org.springframework.boot' apply plugin: 'org.hibernate.orm' It solves error on startup spring-boot app, but still `enableLazyInitialization` option seems not work. – Yuki Yoshida May 22 '18 at 04:03
  • @maxsap do you run the project via gradle or your IDE? – Artem Novikov Aug 17 '18 at 08:48

2 Answers2

0

According to sources it should work, if you have created your build.gradle file properly. In the latest docs it says following.

ext {
    hibernateVersion = 'hibernate-version-you-want'
}

buildscript {
    dependencies {
        classpath "org.hibernate:hibernate-gradle-plugin:$hibernateVersion"
    }
}

hibernate {
    enhance {
        // any configuration goes here
    }
}

Make sure you have the plugin added in the buildscript section, and if you can post your build.gradle it might be more useful as well.

On a sidenote have a look at this question also, in order to resolve your original question of one-to-one lazy initialization.

Maleen Abewardana
  • 11,086
  • 3
  • 36
  • 38
  • I had the buildscript section already defined, I have updated my question to include also the gradle file. – maxsap May 23 '18 at 15:15
0

Refer to following document https://docs.jboss.org/hibernate/orm/5.3/topical/html_single/bytecode/BytecodeEnhancement.html

The Right syntax is as follows

hibernate {
    enhance {
        enableLazyInitialization= true
        enableDirtyTracking = true
        enableAssociationManagement = true
        enableExtendedEnhancement = false
    }
}
Pramod
  • 1