Open antoniosch85 opened 2 years ago
I notice the same issue with my application and today I can confirm it. This is really a serious bug since we are getting incorrect results with OneToMany.
Here is a reproducible jdl.
application {
config {
applicationType monolith
authenticationType jwt
baseName jhcache
blueprints []
buildTool maven
cacheProvider hazelcast
clientFramework angularX
clientPackageManager npm
clientTheme none
creationTimestamp 1640705957630
databaseType sql
devDatabaseType h2Disk
dtoSuffix DTO
enableGradleEnterprise false
enableHibernateCache true
enableSwaggerCodegen false
enableTranslation false
gradleEnterpriseHost ""
jhiPrefix jhi
jhipsterVersion "7.4.1"
jwtSecretKey "ZWJmMTkzOTE3MjY2OTYwYmIwZGQxMTk1YWJiYmU2N2FkMTI1Y2NlMDY3MGI2Y2YyOWZmY2U1MTA2MDc2Mjk5OTNkYmU2NjU5N2EwOGVhOWE4ZWJmNTAyMDRkNTk4MWI1N2U2ZjYxYTMzMmM4ZmI3M2JkOWJhMzc3MjJmYjAxYjY="
languages [en, fr]
messageBroker false
nativeLanguage en
otherModules []
packageName com.mycompany.myapp
prodDatabaseType postgresql
reactive false
searchEngine false
serverPort 8080
serviceDiscoveryType no
skipUserManagement false
testFrameworks []
websocket false
withAdminUi true
}
entities Child, Parent
}
entity Child {
name String
}
entity Parent {
name String
}
relationship OneToMany {
Parent{child} to Child{parent(name)}
}
dto Child, Parent with mapstruct
service Child, Parent with serviceClass
Steps to reproduce
jhipster import-jdl jdlcontent.jh
ParentService.findOne
method to print -ToMany
side.
parentRepository.findById(id).ifPresent(parent -> parent.getChildren().forEach(System.out::println));
ParentService.findOne
method is not printing the correct number of child entities.I am checking for the same issue however I am wondering how many applications have been affected since it is reported for v6.10.5
.
Adding a bounty as the bug is confirmed by you, @pmverma If you know how to fix it, plz go ahead!
It looks like the problem seems to be related to the caching of the old parent entity. When assigning a new parent the old one is not changed and stays in the cache. When you save/update the old parent the cache is consistent again. Not sure if thats the root cause and if thats how the hibernate cache is supposed to work.
It looks like the problem seems to be related to the caching of the old parent entity. When assigning a new parent the old one is not changed and stays in the cache. When you save/update the old parent the cache is consistent again. Not sure if thats the root cause and if thats how the hibernate cache is supposed to work.
If you update the parent the cache is updated, the issue occurs only when a new parent has been inserted. I think it is how the hibernate cache is supposed to work.
The issue here is we are not synchronizing bi-directional associations although we already have the synchronization code in parent classes. How to synchronize bidirectional entity associations with JPA and Hibernate Naturally, we would manage the synchronization from the parent side however if you want to do in child class/service it should work but then again at least we would need to load the parent so we can add a child to it.
Two solutions I can think of as of now.
Code snippet of ChildService.java
/**
* Save a child.
*
* @param childDTO the entity to save.
* @return the persisted entity.
*/
public ChildDTO save(ChildDTO childDTO) {
log.debug("Request to save Child : {}", childDTO);
Child child = childMapper.toEntity(childDTO);
// solution1, syncing starts here
if (Objects.nonNull(child.getParent()) && Objects.nonNull(child.getParent().getId())) {
final var parentOptional = parentRepository.findById(child.getParent().getId());
if (parentOptional.isPresent()) {
final var parent = parentOptional.get();
parent.addChild(child);
}
}
// solution1, syncing ends here
child = childRepository.save(child);
// solution2, syncing starts here
child.getParent().addChild(child);
// solution2, syncing ends here
return childMapper.toDto(child);
}
Solution1 is a more traditional approach but has some concerns.
Service/Repository
class for loading the parent entity. JHipster does not generate such code as of today.Solution2 seems weird but it works and we can use the code we already have. No dependency. Not many lines of code even we have multiple parents.
I would rather like to wait for what experts say. cc @jhipster/developers
I totally agree, loading the parent inside child service is ugly (tried it too). So maybe we can somehow decouple it with some spring events (or jpa events?).
V8 could be the occasion to go modulith
For v7, if there is no major concern I would like to go with solution2. For v8 or future major versions, we still can have some other suitable solution.
@pmverma Are you still available to do a PR?
@OneToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }) does the trick
Overview of the issue
The annotation CacheConcurrencyStrategy.READ_WRITE seems not working. Always an empty result is returned, I need to restart server to see the correct return.
Motivation for or Use Case
I am not able to use the cache. In order to work, I have to eliminate the annotation @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
Reproduce the error
I have 2 entities A and B with one to many relationship. I generated all service and in the entity A I can see:
If I add a new entity B and set the relationship with entity A, my expectation is when I call entityA.getEntitiesB() the inserted entityB is returned but I get always an empty set. If I restart the server the correct list is returned.
Related issues
Suggest a Fix
JHipster Version(s)
v6.10.5
JHipster configuration
Entity configuration(s)
entityName.json
files generated in the.jhipster
directoryBrowsers and Operating System