generator-jhipster: LazyInitializationException on an entity with ManyToMany, pagination and mapstruct
Overview of the issue
Hibernate throws an exception when trying to get all Job entities after creating a Job entity.
Exception in com.jhipster.web.rest.JobResource.getAllJobs() with cause = 'NULL' and exception = 'failed to lazily initialize a collection of role: com.jhipster.domain.Job.tasks, could not initialize proxy - no Session'
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.jhipster.domain.Job.tasks, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:582)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:201)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:561)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132)
at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:163)
at com.jhipster.service.mapper.JobMapperImpl.taskSetToTaskDTOSet(JobMapperImpl.java:140)
at com.jhipster.service.mapper.JobMapperImpl.jobToJobDTO(JobMapperImpl.java:58)
at com.jhipster.service.mapper.JobMapperImpl.jobsToJobDTOs(JobMapperImpl.java:81)
Motivation for or Use Case
This issue only appears when having an entity with a ManyToMany relationship, being paginated (pager, pagination or infinite-scroll) and dto generated with mapstruct. It’s a little specific but if you use the default JDL from JDL Studio you will have the issue.
Reproduce the error
Use the JDL below to generate entities. Create a Job entity with no Task. An exception will be thrown when displaying all Job.
Related issues
Found nothing related.
Suggest a Fix
Maybe by doing an eager load on the ManyToMany relationship like it’s done when Job is not paginated.
JHipster Version(s)
4.3.0
JHipster configuration
JHipster Version(s)
jhipster@0.0.0 /Users/Theo/Documents/perso/jhipster-issues
└── generator-jhipster@4.3.0
JHipster configuration, a .yo-rc.json file generated in the root folder
{
"generator-jhipster": {
"promptValues": {
"packageName": "com.jhipster"
},
"jhipsterVersion": "4.3.0",
"baseName": "jhipster",
"packageName": "com.jhipster",
"packageFolder": "com/jhipster",
"serverPort": "8080",
"authenticationType": "session",
"hibernateCache": "ehcache",
"clusteredHttpSession": false,
"websocket": false,
"databaseType": "sql",
"devDatabaseType": "h2Disk",
"prodDatabaseType": "mysql",
"searchEngine": false,
"messageBroker": false,
"serviceDiscoveryType": false,
"buildTool": "maven",
"enableSocialSignIn": false,
"rememberMeKey": "2b4523900caffa3f139b0240dc516cfd9735ba18",
"clientFramework": "angular1",
"useSass": false,
"clientPackageManager": "yarn",
"applicationType": "monolith",
"testFrameworks": [],
"jhiPrefix": "jhi",
"enableTranslation": false
}
}
Entity configuration(s) entityName.json files generated in the .jhipster directory
Job.json
{
"fluentMethods": true,
"relationships": [
{
"relationshipType": "many-to-many",
"otherEntityRelationshipName": "job",
"relationshipName": "task",
"otherEntityName": "task",
"otherEntityField": "id",
"ownerSide": true
}
],
"fields": [
{
"fieldName": "jobTitle",
"fieldType": "String"
}
],
"changelogDate": "20170420032832",
"entityTableName": "job",
"dto": "mapstruct",
"pagination": "pagination",
"service": "no"
}
Task.json
{
"fluentMethods": true,
"relationships": [
{
"relationshipType": "many-to-many",
"relationshipName": "job",
"otherEntityName": "job",
"ownerSide": false,
"otherEntityRelationshipName": "task"
}
],
"fields": [
{
"fieldName": "title",
"fieldType": "String"
}
],
"changelogDate": "20170420032831",
"entityTableName": "task",
"dto": "mapstruct",
"pagination": "no",
"service": "no"
}
Browsers and Operating System
java version “1.8.0_92” Java™ SE Runtime Environment (build 1.8.0_92-b14) Java HotSpot™ 64-Bit Server VM (build 25.92-b14, mixed mode)
git version 2.10.1 (Apple Git-78)
node: v7.8.0
npm: 4.2.0
bower: 1.8.0
gulp: [23:47:04] CLI version 1.2.2 [23:47:04] Local version 3.9.1
yeoman: 1.8.5
yarn: 0.22.0
Docker version 17.03.1-ce, build c6d412e
docker-compose version 1.11.2, build dfed245
Entity configuration(s) entityName.json files generated in the .jhipster directory
JDL
entity Task {
title String
}
entity Job {
jobTitle String
}
relationship ManyToMany {
Job{task} to Task{job}
}
paginate Job with pagination
dto * with mapstruct
Browsers and Operating System
Chrome 57 on OS X El Capitan
- Checking this box is mandatory (this is just to show you read everything)
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 48 (43 by maintainers)
Commits related to this issue
- Merge pull request #6893 from nghib/issue_5629 fix #5629 typos — committed to jhipster/generator-jhipster by jdubois 7 years ago
@gzsombor @jdubois what you think of showing DTO and Filter option only when Service is selected? it will atleast solve these kind of issues
The better solution is to fix the transaction handling :
Basically, you need to access your database from a code block, which is in a ‘JPA/hibernate session’
I just realized that many-to-many are currently fetched eagerly in the repository (
findAllWithEagerRelationships,findOneWithEagerRelationships). I don’t think this is a good idea:Yes I would also prefer to suppress the DTO and filtering option when service is not selected. It will reduce lot of headaches for us
Thanks & Regards, Deepu
On Mon, Dec 4, 2017 at 1:59 PM, Mathieu ABOU-AICHI <notifications@github.com
My position is still the same :
The main problem for that approach would be generation since we don’t know which entities point to the entity we are generating.(we know if a one-to-many is unidir when generating the many side since it’s the owner of the relationship in this case, and not when the rel is bidir)Other advantages of the REST link:
For the form, it could be done as an HATEOAS-compliant
linksproperty in the response: GET /api/jobs (paginated)GET /api/tasks (not paginated)
GET /api/tasks/1002/jobs (paginated) where task 1002 is linked to job 1001 but not to job 1003
Nobody is working on it because that doesn’t seem to interest anyone… People just have better things to do, that’s all. I would have a solution if I had time to work on this: as far as I’m concerned, MapStruct is still marked BETA, and I’m not using it personally, so this is not my priority.
If you change the line: “service all with serviceImpl except Employee, Job” by: “service all with serviceImpl”
If “Job” has service, it works correctly