Spring - Same entity detached on the #EventListener but attached in the #Service class - spring

I have following classes in my Spring application: TaskService and DevStartup.
When application starts DevStartup is run, but the Tag("Home") is seen as detached entity on tasksRepository.save(task) which throws detached entity exception during startup.
#Component
#AllArgsConstructor
#Slf4j
#Profile("dev")
public class DevStartup {
private final TagsService tagsService;
private final TagsRepository tagsRepository;
private final TasksRepository tasksRepository;
private final Clock clock;
private final EntityManager entityManager;
#EventListener(ApplicationReadyEvent.class)
public void initializeApplication() {
insertTags();
insertTasks();
}
private void insertTags() {
List<Tag> tags = Arrays.asList(
new Tag("Home")
);
tagsRepository.saveAll(tags);
}
private void insertTasks() {
Task task = new Task("Run a webinar", "Zoom.us", clock.time());
Set<Tag> tagsForTask = Stream.of("Home")
.map(tag -> tagsService.findByName(tag).orElseGet(() -> new Tag(tag)))
.collect(Collectors.toSet());
task.addTags(tagsForTask);
tasksRepository.save(task); // ERROR -> Tag("Home") Entity Detached!!!!!
}
}
At the same time I'm having exact code in the TaskService class and I call it with the same arguments from my REST Controller.
addTask("Task title", "Task description", Stream.of("Home").collect(toSet());
And this time, the Tag("Home") entity is attached
#Service
#RequiredArgsConstructor
public class TasksService {
private final StorageService storageService;
private final TasksRepository tasksRepository;
private final TagsService tagsService;
private final Clock clock;
private final EntityManager entityManager;
public Task addTask(String title, String description, Set<String> tags) {
Task task = new Task(
title,
description,
clock.time()
);
Set<Tag> tagsForTask = tags.stream()
.map(tag -> tagsService.findByName(tag).orElseGet(() -> new Tag(tag)))
.collect(Collectors.toSet());
task.addTags(tagsForTask);
tasksRepository.save(task); // OK -> Tag("Home") Entity Attached
return task;
}
// ...
}
What is the difference between those two and why entity is detached in one case and attached in the other?
I am using Spring Boot 2.1.9 with Hibernate 5 and JPA (Spring Data JPA project).
TagsService.findByName() is just calling TagsRepository.findByNameContainingIgnoreCase:
public interface TagsRepository extends JpaRepository<Tag, Long> {
Optional<Tag> findByNameContainingIgnoreCase(String name);
}
Update
Here are the trace logs from DevStartup. I can spot that session is closed right after fetching the Tag from TagService, and then opened again for saving Task (this is why I'm getting the detached entity exception).
2020-01-25 23:06:46.774 TRACE 33093 --- [ restartedMain] org.hibernate.internal.SessionImpl : Automatically flushing session
2020-01-25 23:06:46.778 TRACE 33093 --- [ restartedMain] org.hibernate.internal.SessionImpl : SessionImpl#afterTransactionCompletion(successful=true, delayed=false)
2020-01-25 23:06:46.779 TRACE 33093 --- [ restartedMain] org.hibernate.internal.SessionImpl : Closing session [d8094673-13fd-4b7e-af38-4aa01afbcaf7]
2020-01-25 23:06:46.789 TRACE 33093 --- [ restartedMain] org.hibernate.internal.SessionImpl : Opened Session [d2c0c551-6523-466f-ab07-a8c1455c62a4] at timestamp: 1579990006789
2020-01-25 23:06:46.848 DEBUG 33093 --- [ restartedMain] org.hibernate.SQL : select tag0_.id as id1_2_, tag0_.name as name2_2_ from tag tag0_ where upper(tag0_.name) like upper(?) escape ?
Hibernate: select tag0_.id as id1_2_, tag0_.name as name2_2_ from tag tag0_ where upper(tag0_.name) like upper(?) escape ?
2020-01-25 23:06:46.850 TRACE 33093 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [%Home%]
2020-01-25 23:06:46.850 TRACE 33093 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [CHAR] - [\]
2020-01-25 23:06:46.855 TRACE 33093 --- [ restartedMain] org.hibernate.internal.SessionImpl : Closing session [d2c0c551-6523-466f-ab07-a8c1455c62a4]
2020-01-25 23:06:46.860 TRACE 33093 --- [ restartedMain] org.hibernate.internal.SessionImpl : Opened Session [6caeb288-a608-4aa7-a5f9-091c69900815] at timestamp: 1579990006860
2020-01-25 23:06:46.867 DEBUG 33093 --- [ restartedMain] org.hibernate.SQL : insert into task (id, uuid, created_at, description, title) values (null, ?, ?, ?, ?)
Hibernate: insert into task (id, uuid, created_at, description, title) values (null, ?, ?, ?, ?)
2020-01-25 23:06:46.868 TRACE 33093 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [fc9c993b-eccf-45ff-b49a-12498b6e62eb]
2020-01-25 23:06:46.868 TRACE 33093 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [TIMESTAMP] - [2020-01-25T23:06:46.785455]
2020-01-25 23:06:46.870 TRACE 33093 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [Zoom.us]
2020-01-25 23:06:46.872 TRACE 33093 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [Run a webinar]
2020-01-25 23:06:46.879 TRACE 33093 --- [ restartedMain] org.hibernate.internal.SessionImpl : SessionImpl#afterTransactionCompletion(successful=false, delayed=false)
2020-01-25 23:06:46.880 TRACE 33093 --- [ restartedMain] org.hibernate.internal.SessionImpl : Closing session [6caeb288-a608-4aa7-a5f9-091c69900815]
2020-01-25 23:06:46.900 ERROR 33093 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
Below are the logs when running code from TaskService. The session is not closed between fetching tags and saving tasks.
2020-01-25 23:10:24.966 TRACE 33194 --- [ restartedMain] org.hibernate.internal.SessionImpl : Closing session [f3ea3806-3c65-4269-81b4-ba8bc1abf2af]
2020-01-25 23:10:55.518 INFO 33194 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-01-25 23:10:55.519 INFO 33194 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-01-25 23:10:55.533 INFO 33194 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 14 ms
2020-01-25 23:10:55.553 TRACE 33194 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : Opened Session [61d3d232-2d92-4002-8e4c-cedb0278a2e9] at timestamp: 1579990255552
2020-01-25 23:10:55.858 INFO 33194 --- [nio-8080-exec-1] p.s.t.tasks.boundary.TasksController : Storing new task: CreateTaskRequest(title=Dokończyć Moduł 8, description=Jpa i Hibernate cz. 2, attachmentComment=null, tags=[Home])
2020-01-25 23:10:55.914 DEBUG 33194 --- [nio-8080-exec-1] org.hibernate.SQL : select tag0_.id as id1_2_, tag0_.name as name2_2_ from tag tag0_ where upper(tag0_.name) like upper(?) escape ?
Hibernate: select tag0_.id as id1_2_, tag0_.name as name2_2_ from tag tag0_ where upper(tag0_.name) like upper(?) escape ?
2020-01-25 23:10:55.920 TRACE 33194 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [%Home%]
2020-01-25 23:10:55.920 TRACE 33194 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [CHAR] - [\]
2020-01-25 23:10:59.218 DEBUG 33194 --- [nio-8080-exec-1] org.hibernate.SQL : insert into task (id, uuid, created_at, description, title) values (null, ?, ?, ?, ?)
Hibernate: insert into task (id, uuid, created_at, description, title) values (null, ?, ?, ?, ?)
2020-01-25 23:10:59.218 TRACE 33194 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [bac8dacb-9424-4c6e-9a3a-860973ebc350]
2020-01-25 23:10:59.219 TRACE 33194 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [TIMESTAMP] - [2020-01-25T23:10:55.878153]
2020-01-25 23:10:59.223 TRACE 33194 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [Jpa i Hibernate cz. 2]
2020-01-25 23:10:59.224 TRACE 33194 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [Dokończyć Moduł 8]
2020-01-25 23:10:59.244 TRACE 33194 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : SessionImpl#beforeTransactionCompletion()
2020-01-25 23:10:59.244 TRACE 33194 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : Automatically flushing session
2020-01-25 23:10:59.262 DEBUG 33194 --- [nio-8080-exec-1] org.hibernate.SQL : insert into tags_tasks (task_id, tag_id) values (?, ?)
Hibernate: insert into tags_tasks (task_id, tag_id) values (?, ?)
2020-01-25 23:10:59.263 TRACE 33194 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2020-01-25 23:10:59.264 TRACE 33194 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [1]
2020-01-25 23:10:59.273 TRACE 33194 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : SessionImpl#afterTransactionCompletion(successful=true, delayed=false)

Most likely, you have Open Session In View enabled
If you are running a web application, Spring Boot by default registers OpenEntityManagerInViewInterceptor to apply the “Open EntityManager in View” pattern, to allow for lazy loading in web views. If you do not want this behavior, you should set spring.jpa.open-in-view to false in your application.properties.
This will open the session when request starts and and closes it after the request processing is done. The interceptor is run for web request, but not in case of ApplicationReadyEvent event listener.
You may want to use #Transactional to extend the lifetime of the session when you are not relying on open session in view. See https://stackoverflow.com/a/24713402/1570854:
In Spring, there is a one-to-one correspondence between the business transaction demarcated by #Transactional, and the hibernate Session.
That is, when a business transaction is begun by invoking a #Transactional method, the hibernate session is created (a TransactionManager may delay the actual creation until the session is first used). Once that method completes, the business transaction is committed or rolled back, which closes the hibernate session.
Many consider open session in view to be an anti-pattern: https://vladmihalcea.com/the-open-session-in-view-anti-pattern/

Related

Spring Data Rest doesn't rollback after Access Denied Exception

I have an application built with Spring Data Rest, when saving an entity using an unauthorized account through preAuthorize, the system throws the Access Denied exception, however the registration is performed. Analyzing the log below it is possible to see a jpaTransaction performing a flush and updating the entity before the exception. Can anyone tell me how to avoid saving in this case or how I can perform a rollback?
... com.mysql.cj.jdbc.result.ResultSetImpl#2393ebf8]
2022-10-19 13:20:11.320 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Closing prepared statement [HikariProxyPreparedStatement#91893682 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: select chain0_.category_id as category1_3_0_, c... where chain0_.category_id=13122]
2022-10-19 13:20:11.321 TRACE 705721 --- [nio-8080-exec-6] o.h.e.j.i.JdbcCoordinatorImpl : Starting after statement execution processing [ON_CLOSE]
2022-10-19 13:20:11.321 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.StatefulPersistenceContext : Initializing non-lazy collections
2022-10-19 13:20:11.321 DEBUG 705721 --- [nio-8080-exec-6] stractLoadPlanBasedCollectionInitializer : Done loading collection
2022-10-19 13:20:11.321 TRACE 705721 --- [nio-8080-exec-6] DefaultInitializeCollectionEventListener : Collection initialized
2022-10-19 13:20:13.373 DEBUG 705721 --- [SchedulerThread] o.q.c.QuartzSchedulerThread : batch acquisition of 0 triggers
2022-10-19 13:20:13.423 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : com.springboot.api.entities.Category.name is dirty
2022-10-19 13:20:13.423 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : com.springboot.api.entities.Category.updateDate is dirty
2022-10-19 13:20:13.423 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.DefaultFlushEntityEventListener : Found dirty properties [[com.springboot.api.entities.Category#13122]] : [name, updateDate]
2022-10-19 13:20:13.423 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.Versioning : Incrementing: 76 to 77
2022-10-19 13:20:13.424 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.i.Collections : Collection found: [com.springboot.api.entities.Category.chain#13122], was: [com.springboot.api.entities.Category.chain#13122] (initialized)
2022-10-19 13:20:13.424 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Processing unreferenced collections
2022-10-19 13:20:13.425 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Scheduling collection removes/(re)creates/updates
2022-10-19 13:20:13.425 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Flushed: 0 insertions, 1 updates, 0 deletions to 2 objects
2022-10-19 13:20:13.425 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Flushed: 0 (re)creations, 0 updates, 0 removals to 1 collections
2022-10-19 13:20:13.425 DEBUG 705721 --- [nio-8080-exec-6] o.h.i.u.EntityPrinter : Listing entities:
2022-10-19 13:20:13.425 DEBUG 705721 --- [nio-8080-exec-6] o.h.i.u.EntityPrinter : com.springboot.api.entities.Category{chain=[], updateDate=2022-10-19T13:20:08.095108, typeCategoryResultReports=NOT_APPLIED, businessAccount=com.springboot.api.entities.BusinessAccount#13119, description=Conta somatória de vendas dos produtos e serviços., typeResultReports=NOT_APPLIED_TO_DRE, typeCategory=INCOME, version=77, ordder=1, deleted=false, name=RECEITAS DE VENDAS 789, parentCategory=null, id=13122, createDate=2022-07-25T11:06:40, enumerated=1}
2022-10-19 13:20:13.426 DEBUG 705721 --- [nio-8080-exec-6] o.h.i.u.EntityPrinter : com.springboot.api.entities.BusinessAccount{updateDate=2022-07-25T11:07:46, active=true, contactPerson=Erik, version=1, legalName=Erick e Tatiane Restaurante Ltda, deleted=false, blocked=false, phone=1138234204, name=ERIT Restaurante Ltda, tin=02669055000114, id=13119, businessAccountParent=null, email=timlerirde#vusra.com, createDate=2022-07-25T11:06:36}
2022-10-19 13:20:13.426 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.DefaultAutoFlushEventListener : Don't need to execute flush
2022-10-19 13:20:13.426 TRACE 705721 --- [nio-8080-exec-6] o.h.e.q.s.HQLQueryPlan : Find: select b from BusinessAccount b where b.deleted = false and b.id = :id
2022-10-19 13:20:13.426 TRACE 705721 --- [nio-8080-exec-6] o.h.e.s.QueryParameters : Named parameters: {id=13119}
2022-10-19 13:20:13.426 DEBUG 705721 --- [nio-8080-exec-6] o.h.SQL : select businessac0_.id as id1_1_, ... where businessac0_.deleted=0 and businessac0_.id=?
2022-10-19 13:20:13.427 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Registering statement [HikariProxyPreparedStatement#1827444228 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: select businessac0_.id as id1_1_, businessac0_.active as active2_1_, ... businessac0_.id=** NOT SPECIFIED **]
2022-10-19 13:20:13.427 TRACE 705721 --- [nio-8080-exec-6] o.h.e.j.i.JdbcCoordinatorImpl : Registering last query statement [HikariProxyPreparedStatement#1827444228 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: select businessac0_.id as id1_1_, businessac0_.active as active2_1_, ... businessac0_.version as version13_1_ from business_account businessac0_ where businessac0_.deleted=0 and businessac0_.id=** NOT SPECIFIED **]
2022-10-19 13:20:13.428 TRACE 705721 --- [nio-8080-exec-6] o.h.t.d.s.BasicBinder : binding parameter [1] as [BIGINT] - [13119]
2022-10-19 13:20:13.428 TRACE 705721 --- [nio-8080-exec-6] o.h.l.Loader : Bound [2] parameters total
2022-10-19 13:20:13.583 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Registering result set [HikariProxyResultSet#212627179 wrapping com.mysql.cj.jdbc.result.ResultSetImpl#305c88ad]
2022-10-19 13:20:13.584 TRACE 705721 --- [nio-8080-exec-6] o.h.l.Loader : Processing result set
2022-10-19 13:20:13.584 DEBUG 705721 --- [nio-8080-exec-6] o.h.l.Loader : Result set row: 0
2022-10-19 13:20:13.584 TRACE 705721 --- [nio-8080-exec-6] o.h.t.d.s.BasicExtractor : extracted value ([id1_1_] : [BIGINT]) - [13119]
2022-10-19 13:20:13.585 DEBUG 705721 --- [nio-8080-exec-6] o.h.l.Loader : Result row: EntityKey[com.springboot.api.entities.BusinessAccount#13119]
2022-10-19 13:20:13.585 TRACE 705721 --- [nio-8080-exec-6] o.h.l.Loader : Done processing result set (1 rows)
2022-10-19 13:20:13.585 TRACE 705721 --- [nio-8080-exec-6] o.h.l.Loader : Total objects hydrated: 0
2022-10-19 13:20:13.586 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing statement [HikariProxyPreparedStatement#1827444228 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: select businessac0_.id as id1_1_, businessac0_.active as active2_1_, businessac0_.blocked as blocked3_1_, businessac0_.business_account_parent_id as busines14_1_, businessac0_.contact_person as contact_4_1_, businessac0_.create_date as create_d5_1_, businessac0_.deleted as deleted6_1_, businessac0_.email as email7_1_, businessac0_.legal_name as legal_na8_1_, businessac0_.name as name9_1_, businessac0_.phone as phone10_1_, businessac0_.tin as tin11_1_, businessac0_.update_date as update_12_1_, businessac0_.version as version13_1_ from business_account businessac0_ where businessac0_.deleted=0 and businessac0_.id=13119]
2022-10-19 13:20:13.586 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Closing result set [HikariProxyResultSet#212627179 wrapping com.mysql.cj.jdbc.result.ResultSetImpl#305c88ad]
2022-10-19 13:20:13.586 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Closing prepared statement [HikariProxyPreparedStatement#1827444228 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: select businessac0_.id as id1_1_, businessac0_.active as active2_1_, businessac0_.blocked as blocked3_1_, businessac0_.business_account_parent_id as busines14_1_, businessac0_.contact_person as contact_4_1_, businessac0_.create_date as create_d5_1_, businessac0_.deleted as deleted6_1_, businessac0_.email as email7_1_, businessac0_.legal_name as legal_na8_1_, businessac0_.name as name9_1_, businessac0_.phone as phone10_1_, businessac0_.tin as tin11_1_, businessac0_.update_date as update_12_1_, businessac0_.version as version13_1_ from business_account businessac0_ where businessac0_.deleted=0 and businessac0_.id=13119]
2022-10-19 13:20:13.586 TRACE 705721 --- [nio-8080-exec-6] o.h.e.j.i.JdbcCoordinatorImpl : Starting after statement execution processing [ON_CLOSE]
2022-10-19 13:20:13.586 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.StatefulPersistenceContext : Initializing non-lazy collections
2022-10-19 13:20:13.589 TRACE 705721 --- [nio-8080-exec-6] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2022-10-19 13:20:13.589 TRACE 705721 --- [nio-8080-exec-6] o.s.o.j.JpaTransactionManager : Triggering beforeCommit synchronization
2022-10-19 13:20:13.589 TRACE 705721 --- [nio-8080-exec-6] o.s.o.j.JpaTransactionManager : Triggering beforeCompletion synchronization
2022-10-19 13:20:13.589 DEBUG 705721 --- [nio-8080-exec-6] o.s.o.j.JpaTransactionManager : Initiating transaction commit
2022-10-19 13:20:13.589 DEBUG 705721 --- [nio-8080-exec-6] o.s.o.j.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(329218779PersistenceContext[entityKeys=[EntityKey[com.springboot.api.entities.Category#13122], EntityKey[com.springboot.api.entities.BusinessAccount#13119]], collectionKeys=[CollectionKey[com.springboot.api.entities.Category.chain#13122]]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
2022-10-19 13:20:13.589 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.t.i.TransactionImpl : committing
2022-10-19 13:20:13.590 TRACE 705721 --- [nio-8080-exec-6] cResourceLocalTransactionCoordinatorImpl : ResourceLocalTransactionCoordinatorImpl#beforeCompletionCallback
2022-10-19 13:20:13.590 TRACE 705721 --- [nio-8080-exec-6] o.h.i.SessionImpl : SessionImpl#beforeTransactionCompletion()
2022-10-19 13:20:13.590 TRACE 705721 --- [nio-8080-exec-6] o.h.i.SessionImpl : Automatically flushing session
2022-10-19 13:20:13.590 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Flushing session
2022-10-19 13:20:13.590 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Processing flush-time cascades
2022-10-19 13:20:13.590 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.Cascade : Processing cascade ACTION_PERSIST_ON_FLUSH for: com.springboot.api.entities.Category
2022-10-19 13:20:13.590 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.Cascade : Done processing cascade ACTION_PERSIST_ON_FLUSH for: com.springboot.api.entities.Category
2022-10-19 13:20:13.591 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.Cascade : Processing cascade ACTION_PERSIST_ON_FLUSH for: com.springboot.api.entities.BusinessAccount
2022-10-19 13:20:13.592 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.Cascade : Done processing cascade ACTION_PERSIST_ON_FLUSH for: com.springboot.api.entities.BusinessAccount
2022-10-19 13:20:13.592 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Dirty checking collections
2022-10-19 13:20:13.592 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Flushing entities and processing referenced collections
2022-10-19 13:20:13.593 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : com.springboot.api.entities.Category.name is dirty
2022-10-19 13:20:13.593 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : com.springboot.api.entities.Category.updateDate is dirty
2022-10-19 13:20:13.593 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : com.springboot.api.entities.Category.version is dirty
2022-10-19 13:20:13.593 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.DefaultFlushEntityEventListener : Found dirty properties [[com.springboot.api.entities.Category#13122]] : [name, updateDate, version]
2022-10-19 13:20:13.593 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.DefaultFlushEntityEventListener : Updating entity: [com.springboot.api.entities.Category#13122]
2022-10-19 13:20:16.443 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : com.springboot.api.entities.Category.name is dirty
2022-10-19 13:20:16.444 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : com.springboot.api.entities.Category.updateDate is dirty
2022-10-19 13:20:16.444 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : com.springboot.api.entities.Category.version is dirty
2022-10-19 13:20:16.444 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.DefaultFlushEntityEventListener : Found dirty properties [[com.springboot.api.entities.Category#13122]] : [name, updateDate, version]
2022-10-19 13:20:16.444 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.Versioning : Incrementing: 76 to 77
2022-10-19 13:20:16.445 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.i.Collections : Collection found: [com.springboot.api.entities.Category.chain#13122], was: [com.springboot.api.entities.Category.chain#13122] (initialized)
2022-10-19 13:20:16.445 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Processing unreferenced collections
2022-10-19 13:20:16.445 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Scheduling collection removes/(re)creates/updates
2022-10-19 13:20:16.445 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Flushed: 0 insertions, 1 updates, 0 deletions to 2 objects
2022-10-19 13:20:16.445 DEBUG 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Flushed: 0 (re)creations, 0 updates, 0 removals to 1 collections
2022-10-19 13:20:16.445 DEBUG 705721 --- [nio-8080-exec-6] o.h.i.u.EntityPrinter : Listing entities:
2022-10-19 13:20:16.446 DEBUG 705721 --- [nio-8080-exec-6] o.h.i.u.EntityPrinter : com.springboot.api.entities.Category{chain=[], updateDate=2022-10-19T13:20:13.593846, typeCategoryResultReports=NOT_APPLIED, businessAccount=com.springboot.api.entities.BusinessAccount#13119, description=Conta somatória de vendas dos produtos e serviços., typeResultReports=NOT_APPLIED_TO_DRE, typeCategory=INCOME, version=77, ordder=1, deleted=false, name=RECEITAS DE VENDAS 789, ...
2022-10-19 13:20:16.446 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Executing flush
2022-10-19 13:20:16.447 TRACE 705721 --- [nio-8080-exec-6] o.h.v.i.e.c.SimpleConstraintTree : Validating value RECEITAS DE VENDAS 789 against constraint defined by ConstraintDescriptorImpl{annotation=j.v.c.NotEmpty, payloads=[], hasComposingConstraints=true, isReportAsSingleInvalidConstraint=false, elementType=FIELD, definedOn=DEFINED_LOCALLY, groups=[interface javax.validation.groups.Default], attributes={groups=[Ljava.lang.Class;#7375d1f6, message={name.required}, payload=[Ljava.lang.Class;#261e67fb}, constraintType=GENERIC, valueUnwrapping=DEFAULT}.
2022-10-19 13:20:16.454 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : Updating entity: [com.springboot.api.entities.Category#13122]
2022-10-19 13:20:16.454 TRACE 705721 --- [nio-8080-exec-6] o.h.p.e.AbstractEntityPersister : Existing version: 76 -> New version:77
2022-10-19 13:20:16.454 DEBUG 705721 --- [nio-8080-exec-6] o.h.SQL : update category set business_account_id=?, create_date=?, deleted=?, description=?, enumerated=?, name=?, ordder=?, parent_category_id=?, type_category=?, type_category_result_reports=?, type_result_reports=?, update_date=?, version=? where id=? and version=?
...
2022-10-19 13:20:16.461 TRACE 705721 --- [nio-8080-exec-6] o.h.t.d.s.BasicBinder : binding parameter [15] as [INTEGER] - [76]
2022-10-19 13:20:16.627 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing statement [HikariProxyPreparedStatement#1680526329 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: update category set business_account_id=13119, create_date='2022-07-25 11:06:40.0', deleted=0, description='Conta somatória de vendas dos produtos e serviços.', enumerated='1', name='RECEITAS DE VENDAS 789', ordder='1', parent_category_id=null, type_category='INCOME', type_category_result_reports='NOT_APPLIED', type_result_reports='NOT_APPLIED_TO_DRE', update_date='2022-10-19 13:20:13.593846', version=77 where id=13122 and version=76]
2022-10-19 13:20:16.628 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Closing prepared statement [HikariProxyPreparedStatement#1680526329 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: update category set business_account_id=13119, create_date='2022-07-25 11:06:40.0', deleted=0, description='Conta somatória de vendas dos produtos e serviços.', enumerated='1', name='RECEITAS DE VENDAS 789', ordder='1', parent_category_id=null, type_category='INCOME', type_category_result_reports='NOT_APPLIED', type_result_reports='NOT_APPLIED_TO_DRE', update_date='2022-10-19 13:20:13.593846', version=77 where id=13122 and version=76]
2022-10-19 13:20:16.628 TRACE 705721 --- [nio-8080-exec-6] o.h.e.j.i.JdbcCoordinatorImpl : Starting after statement execution processing [ON_CLOSE]
2022-10-19 13:20:16.629 TRACE 705721 --- [nio-8080-exec-6] o.h.e.j.i.JdbcCoordinatorImpl : Starting after statement execution processing [ON_CLOSE]
2022-10-19 13:20:16.629 TRACE 705721 --- [nio-8080-exec-6] o.h.e.i.AbstractFlushingEventListener : Post flush
2022-10-19 13:20:16.629 TRACE 705721 --- [nio-8080-exec-6] .t.i.SynchronizationRegistryStandardImpl : SynchronizationRegistryStandardImpl.notifySynchronizationsBeforeTransactionCompletion
2022-10-19 13:20:16.629 TRACE 705721 --- [nio-8080-exec-6] j.i.AbstractLogicalConnectionImplementor : Preparing to commit transaction via JDBC Connection.commit()
2022-10-19 13:20:16.786 TRACE 705721 --- [nio-8080-exec-6] j.i.AbstractLogicalConnectionImplementor : Transaction committed via JDBC Connection.commit()
2022-10-19 13:20:16.787 TRACE 705721 --- [nio-8080-exec-6] j.i.AbstractLogicalConnectionImplementor : re-enabling auto-commit on JDBC Connection after completion of JDBC-based transaction
2022-10-19 13:20:16.940 TRACE 705721 --- [nio-8080-exec-6] j.i.AbstractLogicalConnectionImplementor : LogicalConnection#afterTransaction
2022-10-19 13:20:16.940 TRACE 705721 --- [nio-8080-exec-6] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources
2022-10-19 13:20:16.941 TRACE 705721 --- [nio-8080-exec-6] cResourceLocalTransactionCoordinatorImpl : ResourceLocalTransactionCoordinatorImpl#afterCompletionCallback(true)
2022-10-19 13:20:16.941 TRACE 705721 --- [nio-8080-exec-6] .t.i.SynchronizationRegistryStandardImpl : SynchronizationRegistryStandardImpl.notifySynchronizationsAfterTransactionCompletion(3)
2022-10-19 13:20:16.941 TRACE 705721 --- [nio-8080-exec-6] o.h.i.SessionImpl : SessionImpl#afterTransactionCompletion(successful=true, delayed=false)
2022-10-19 13:20:16.941 TRACE 705721 --- [nio-8080-exec-6] o.s.o.j.JpaTransactionManager : Triggering afterCommit synchronization
2022-10-19 13:20:16.941 TRACE 705721 --- [nio-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Clearing transaction synchronization
2022-10-19 13:20:16.941 TRACE 705721 --- [nio-8080-exec-6] o.s.o.j.JpaTransactionManager : Triggering afterCompletion synchronization
2022-10-19 13:20:16.941 TRACE 705721 --- [nio-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.jdbc.datasource.ConnectionHolder#710d834f] for key [HikariDataSource (HikariPool-10)] from thread [http-nio-8080-exec-6]
2022-10-19 13:20:16.942 DEBUG 705721 --- [nio-8080-exec-6] o.s.o.j.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
2022-10-19 13:20:16.952 TRACE 705721 --- [nio-8080-exec-6] .w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: [org.springframework.data.rest.webmvc.RootResourceInformation#6e5097f2, Resource { content: Category(id=13122, name=RECEITAS DE VENDAS 789, description=Conta somatória de vendas dos produtos e serviços., parentCategory=null, chain=null, typeCategory=INCOME, typeResultReports=NOT_APPLIED_TO_DRE, ordder=1, typeCategoryResultReports=NOT_APPLIED, businessAccount=BusinessAccount(id=13119, name=ERIT Restaurante Ltda, legalName=Erick e Tatiane Restaurante Ltda, tin=02669055000114, email=timlerirde#vusra.com, phone=1138234204, contactPerson=Erik, businessAccountParent=null, active=true, blocked=false, deleted=false, createDate=2022-07-25T11:06:36, updateDate=2022-07-25T11:07:46, version=1), deleted=false, createDate=2022-07-25T11:06:40, updateDate=2022-10-19T13:20:13.593846, version=76, enumerated=1, unselectable=false), links: [] }, 13122, org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler#299ef425, null, application/json;charset=UTF-8]
...
2022-10-19 13:20:16.959 TRACE 705721 --- [nio-8080-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'persistentEntities'
2022-10-19 13:20:16.960 TRACE 705721 --- [nio-8080-exec-6] .PrePostAnnotationSecurityMetadataSource : Looking for Pre/Post annotations for method 'save' on target class 'class com.sun.proxy.$Proxy552'
2022-10-19 13:20:16.961 DEBUG 705721 --- [nio-8080-exec-6] .PrePostAnnotationSecurityMetadataSource : #org.springframework.security.access.prepost.PreAuthorize(value=hasAuthority('ROLE_ADMIN') or (#category.businessAccount.id == principal.businessAccountId && hasAuthority('MODULE_FINANCE_AND_ACCOUNTING_WRITE'))) found on specific method: public final com.springboot.api.entities.Category com.sun.proxy.$Proxy552.save(com.springboot.api.entities.Category)
2022-10-19 13:20:16.961 DEBUG 705721 --- [nio-8080-exec-6] m.DelegatingMethodSecurityMetadataSource : Caching method [CacheKey[com.sun.proxy.$Proxy552; public abstract com.springboot.api.entities.Category com.springboot.api.repositories.CategoryRepository.save(com.springboot.api.entities.Category)]] with attributes [[authorize: 'hasAuthority('ROLE_ADMIN') or (#category.businessAccount.id == principal.businessAccountId && hasAuthority('MODULE_FINANCE_AND_ACCOUNTING_WRITE'))', filter: 'null', filterTarget: 'null']]
2022-10-19 13:20:16.972 TRACE 705721 --- [nio-8080-exec-6] .PrePostAnnotationSecurityMetadataSource : Looking for Pre/Post annotations for method 'save' on target class 'class org.springframework.data.jpa.repository.support.SimpleJpaRepository'
2022-10-19 13:20:16.974 DEBUG 705721 --- [nio-8080-exec-6] .PrePostAnnotationSecurityMetadataSource : #org.springframework.security.access.prepost.PreAuthorize(value=hasAuthority('ROLE_ADMIN') or (#category.businessAccount.id == principal.businessAccountId && hasAuthority('MODULE_FINANCE_AND_ACCOUNTING_WRITE'))) found on specific method: public abstract com.springboot.api.entities.Category com.springboot.api.repositories.CategoryRepository.save(com.springboot.api.entities.Category)
...
2022-10-19 13:20:16.975 DEBUG 705721 --- [nio-8080-exec-6] o.s.s.a.i.a.MethodSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#5ebb3b09: Principal: com.springboot.api.security.JwtUser#37c7e936; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_OPERATOR, MODULE_ACCOUNTS_MANAGEMENT_READ, MODULE_USERS_MANAGEMENT_READ, MODULE_HUMAN_RESOURCE_READ, MODULE_SALES_AND_MARKETING_READ, MODULE_PURCHASE_READ, MODULE_FINANCE_AND_ACCOUNTING_READ, MODULE_CUSTOMERS_RELATIONSHIP_MANAGEMENT_READ
2022-10-19 13:20:16.992 DEBUG 705721 --- [nio-8080-exec-6] o.s.s.a.v.AffirmativeBased : Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter#261e06ac, returned: -1
2022-10-19 13:20:16.992 DEBUG 705721 --- [nio-8080-exec-6] o.s.s.a.v.AffirmativeBased : Voter: org.springframework.security.access.annotation.Jsr250Voter#2b59105d, returned: 0
2022-10-19 13:20:16.992 DEBUG 705721 --- [nio-8080-exec-6] o.s.s.a.v.AffirmativeBased : Voter: org.springframework.security.access.vote.RoleVoter#ef6ea6b, returned: 0
2022-10-19 13:20:16.992 DEBUG 705721 --- [nio-8080-exec-6] o.s.s.a.v.AffirmativeBased : Voter: org.springframework.security.access.vote.AuthenticatedVoter#1e3b3303, returned: 0
2022-10-19 13:20:17.025 TRACE 705721 --- [nio-8080-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'delegatingApplicationListener'
2022-10-19 13:20:17.025 TRACE 705721 --- [nio-8080-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'springApplicationAdminRegistrar'
2022-10-19 13:20:17.025 TRACE 705721 --- [nio-8080-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'liveReloadServerEventListener'
2022-10-19 13:20:17.036 DEBUG 705721 --- [nio-8080-exec-6] .m.m.a.ExceptionHandlerExceptionResolver : Using #ExceptionHandler com.springboot.api.controllers.ExceptionHandlerController#handleAccessDeniedException(AccessDeniedException, WebRequest)
2022-10-19 13:20:17.036 TRACE 705721 --- [nio-8080-exec-6] .w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: [org.springframework.security.access.AccessDeniedException: Access is denied, ServletWebRequest: uri=/categories/13122;client=0:0:0:0:0:0:0:1;user=jo#eriti.com.br]
2022-10-19 13:20:17.037 ERROR 705721 --- [nio-8080-exec-6] c.s.a.c.ExceptionHandlerController : Access is denied
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65) ~[spring-security-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
Here is my Repository
#PreAuthorize("hasAuthority('ROLE_ADMIN')")
#Transactional(readOnly=true)
#RepositoryRestResource(collectionResourceRel = "categories", path = "categories")
public interface CategoryRepository extends PagingAndSortingRepository<Category, Long> {
#Transactional(readOnly=false)
#PreAuthorize("hasAuthority('ROLE_ADMIN') or (#category.businessAccount.id == principal.businessAccountId && "
+ "hasAuthority('MODULE_FINANCE_AND_ACCOUNTING_WRITE'))")
#Override
<S extends Category> S save(#Param("category") S file);
...
}
Here is my EventHandler
#Component
#RepositoryEventHandler(Category.class)
public class CategoryEventHandler {
#Autowired
private CategoryRepository categoryRepository;
#Autowired
private MessageSource messageSource;
#HandleBeforeCreate
public void handleEntityAccountBeforeCreate(Category category) throws Exception {
...
}
...
}
Here is my Security Config
...
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(AUTH_WHITELIST).permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
httpSecurity.headers().cacheControl();
}
...

Jpa failed to use update() when encountered existing record to save

Mysql database table structure:
database table structure
Customer.java class:
#JsonIgnore
#OneToMany(mappedBy = "customer")
private Set<OrderLine> orderLine = new HashSet<>();
Orderline.java class:
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumns({
#JoinColumn(name = "customer_id", referencedColumnName = "customer_id")})
private Customer customer;
Saving data through OrderLineController class:
#PostMapping("/orderLines")
public ResponseEntity<OrderLine> createOrderLine(#RequestBody OrderLine orderLine) {
OrderLine _orderLine = orderLineRepository.save(orderLine);
return new ResponseEntity<>(_orderLine, HttpStatus.CREATED);
}
Here is my Test file:
OrderLine newOL = new OrderLine(order, product);
newOL.setQty(1);
newOL.setCustomer(customer);
ResponseEntity<OrderLine> respOL = restTemplate.postForEntity("/api/orderLines", newOL, OrderLine.class);
assertEquals(HttpStatus.CREATED, respOL.getStatusCode());
I have previously populated an existing data in the Customer table, and now I tried to create new purchase order based on the existing customer.
In my Test file, when the save() function is executed, Jpa sees the "customer" as a new customer, but it was actually returned from the previous method:
ResponseEntity<Customer> getCustomersByCustomerId(String customerId)
Therefore trying to add a record with the same customer_id produced error, but indeed I was hoping the JpaRepository could figured out the customer_id is the same as the existing customer record, but it doesn't. The Jpa repository tried to insert this record into the customer table, thus resulting Duplicate entry error: I have been searching for possible solution for the past 5 days, but the issue still persist. Your help is much appreciated.
2022-10-06 23:36:23.722 DEBUG 16525 --- [o-auto-1-exec-3] org.hibernate.SQL :
insert
into
customer
(email_address, first_name, last_name, phone, customer_id)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
customer
(email_address, first_name, last_name, phone, customer_id)
values
(?, ?, ?, ?, ?)
2022-10-06 23:36:23.726 TRACE 16525 --- [o-auto-1-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [sammsonwonder#gmail.com]
2022-10-06 23:36:23.726 TRACE 16525 --- [o-auto-1-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [sammson]
2022-10-06 23:36:23.726 TRACE 16525 --- [o-auto-1-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [wonder]
2022-10-06 23:36:23.726 TRACE 16525 --- [o-auto-1-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [0433233333]
2022-10-06 23:36:23.726 TRACE 16525 --- [o-auto-1-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [VARCHAR] - [0433233333]
2022-10-06 23:36:23.738 WARN 16525 --- [o-auto-1-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1062, SQLState: 23000
2022-10-06 23:36:23.739 ERROR 16525 --- [o-auto-1-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : Duplicate entry '0433233333' for key 'customer.PRIMARY'
2022-10-06 23:36:23.744 INFO 16525 --- [o-auto-1-exec-3] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
[ERROR] Tests run: 6, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 2.886 s <<< FAILURE! - in dorinca.mm.rest.SavingsTest
[ERROR] create_1st_order_and_1x_product_for_existing_customer Time elapsed: 0.723 s <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <201 CREATED> but was: <500 INTERNAL_SERVER_ERROR>
at dorinca.mm.rest.SavingsTest.create_1st_order_and_1x_product_for_existing_customer(SavingsTest.java:179)

Hibernate not flushing entity update on transaction commit

This is the transactional service defining the method I use to create a UserCommit and explicitly persisting it (this part works), and in the meantime updating the lastCommit field of the already existent parent entity User. This update doesn't get flushed.
#Transactional
#Service
public class UserCommitService {
#Autowired
private UserService userService;
#Autowired
private UserCommitRepository ucRepo;
public UserCommit createFrom(User user, Integer prodId, String ucType, String stage) {
UserCommit uc = new UserCommit();
uc.setUser(userService.findUserById(user.getId()));
uc.getUser().addUserCommit(uc);
uc.setTime(LocalDateTime.now());
uc.getUser().setLastCommit(uc.getTime());
ucRepo.save(uc);
return uc;
}
}
Here you can read the tracing log:
User gets correctly selected from DB
An inner transaction gets created for ucRepo.save (It's a CRUDRepo method, then I think it's normal) and userCommit gets correctly inserted into DB
EDIT
Why CrudRepository.save creates a new transaction instead of joining the existing one?
Outer transaction gets resumed, but even if the entity show the updated field, it seems this gets ignored by dirty checking, because no insert is logged on commit.
2020-05-31 12:52:36.405 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder#296e6024] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#1826475] bound to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:52:36.406 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(461939992<open>)] for JPA transaction
2020-05-31 12:52:36.406 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [petmenu.services.users.UserCommitService.createFrom]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2020-05-31 12:52:36.407 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle#5ac66b8d]
2020-05-31 12:52:36.407 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.jdbc.datasource.ConnectionHolder#4905e3e7] for key [HikariDataSource (HikariPool-1)] to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:52:36.407 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Initializing transaction synchronization
2020-05-31 12:52:36.407 TRACE 7194 --- [.10-8080-exec-6] o.s.t.i.TransactionInterceptor : Getting transaction for [petmenu.services.users.UserCommitService.createFrom]
2020-05-31 12:53:24.212 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder#296e6024] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#1826475] bound to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:53:24.217 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(461939992<open>)] for JPA transaction
2020-05-31 12:53:24.221 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder#4905e3e7] for key [HikariDataSource (HikariPool-1)] bound to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:53:24.228 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Participating in existing transaction
2020-05-31 12:53:24.232 TRACE 7194 --- [.10-8080-exec-6] o.s.t.i.TransactionInterceptor : Getting transaction for [petmenu.services.users.UserService.findUserById]
2020-05-31 12:53:24.256 TRACE 7194 --- [.10-8080-exec-6] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findUserById]: This method is not transactional.
2020-05-31 12:53:24.265 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.EntityManagerFactoryUtils : Opening JPA EntityManager
2020-05-31 12:53:24.271 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.orm.jpa.EntityManagerHolder#75c27c80] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:53:24.279 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder#75c27c80] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] bound to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:53:24.288 DEBUG 7194 --- [.10-8080-exec-6] org.hibernate.SQL : select user0_.id as id1_0_, user0_.kc_id as kc_id2_0_, user0_.last_commit as last_com3_0_, user0_.name as name4_0_ from user user0_ where user0_.id=?
2020-05-31 12:53:24.298 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [6]
2020-05-31 12:53:24.309 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [INTEGER]) - [6]
2020-05-31 12:53:24.317 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor : extracted value ([kc_id2_0_] : [VARCHAR]) - [80a3b4b1-00d1-4062-a7e5-1927b938c203]
2020-05-31 12:53:24.325 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor : extracted value ([last_com3_0_] : [TIMESTAMP]) - [null]
2020-05-31 12:53:24.332 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name4_0_] : [VARCHAR]) - [user1]
2020-05-31 12:53:24.342 TRACE 7194 --- [.10-8080-exec-6] o.s.t.i.TransactionInterceptor : Completing transaction for [petmenu.services.users.UserService.findUserById]
2020-05-31 12:55:07.918 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata#326a9afb] for key [public abstract java.lang.Object org.springframework.data.repository.CrudRepository.save(java.lang.Object)] to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:07.957 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder#75c27c80] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] bound to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:07.961 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1373582834<open>)] for JPA transaction
2020-05-31 12:55:07.966 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.orm.jpa.EntityManagerHolder#75c27c80] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] from thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:07.970 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Clearing transaction synchronization
2020-05-31 12:55:07.975 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2020-05-31 12:55:07.980 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Opened new EntityManager [SessionImpl(756005269<open>)] for JPA transaction
2020-05-31 12:55:07.987 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle#6860e795]
2020-05-31 12:55:07.992 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.jdbc.datasource.ConnectionHolder#6374741f] for key [HikariDataSource (HikariPool-2)] to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:07.998 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.orm.jpa.EntityManagerHolder#4b2cad26] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:08.002 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Initializing transaction synchronization
2020-05-31 12:55:08.006 TRACE 7194 --- [.10-8080-exec-6] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2020-05-31 12:55:08.226 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder#4b2cad26] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] bound to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:08.392 DEBUG 7194 --- [.10-8080-exec-6] org.hibernate.SQL : select nextval(hibernate_sequence)
2020-05-31 12:55:08.783 TRACE 7194 --- [.10-8080-exec-6] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2020-05-31 12:55:08.787 TRACE 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Triggering beforeCommit synchronization
2020-05-31 12:55:08.791 TRACE 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Triggering beforeCompletion synchronization
2020-05-31 12:55:08.796 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2020-05-31 12:55:08.800 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(756005269<open>)]
2020-05-31 12:55:08.824 DEBUG 7194 --- [.10-8080-exec-6] org.hibernate.SQL : insert into user_commit (uctype, prod_id, stage, time, user, id) values (?, ?, ?, ?, ?, ?)
2020-05-31 12:55:08.832 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [1]
2020-05-31 12:55:08.838 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [INTEGER] - [3]
2020-05-31 12:55:08.845 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [INTEGER] - [0]
2020-05-31 12:55:08.884 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [TIMESTAMP] - [2020-05-31T12:54:58.518530]
2020-05-31 12:55:08.922 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [INTEGER] - [6]
2020-05-31 12:55:08.929 TRACE 7194 --- [.10-8080-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [INTEGER] - [3003]
2020-05-31 12:55:09.043 TRACE 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Triggering afterCommit synchronization
2020-05-31 12:55:09.048 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Clearing transaction synchronization
2020-05-31 12:55:09.052 TRACE 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Triggering afterCompletion synchronization
2020-05-31 12:55:09.056 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.orm.jpa.EntityManagerHolder#4b2cad26] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] from thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:09.062 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.jdbc.datasource.ConnectionHolder#6374741f] for key [HikariDataSource (HikariPool-2)] from thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:09.066 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Closing JPA EntityManager [SessionImpl(756005269<open>)] after transaction
2020-05-31 12:55:09.070 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Resuming suspended transaction after completion of inner transaction
2020-05-31 12:55:09.075 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Initializing transaction synchronization
2020-05-31 12:55:09.080 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.orm.jpa.EntityManagerHolder#75c27c80] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] to thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:55:09.085 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata#326a9afb] for key [public abstract java.lang.Object org.springframework.data.repository.CrudRepository.save(java.lang.Object)] from thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:58:18.989 TRACE 7194 --- [.10-8080-exec-6] o.s.t.i.TransactionInterceptor : Completing transaction for [petmenu.services.users.UserCommitService.createFrom]
2020-05-31 12:58:18.997 TRACE 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Triggering beforeCommit synchronization
2020-05-31 12:58:19.001 TRACE 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Triggering beforeCompletion synchronization
2020-05-31 12:58:19.006 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.orm.jpa.EntityManagerHolder#75c27c80] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6c8672b9] from thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:58:19.071 INFO 7194 --- [.10-8080-exec-6] o.h.c.i.AbstractPersistentCollection : HHH000496: Detaching an uninitialized collection with queued operations from a session: [petmenu.entities.users.User.userCommitList#6]
2020-05-31 12:58:19.075 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2020-05-31 12:58:19.081 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(461939992<open>)]
2020-05-31 12:58:19.095 TRACE 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Triggering afterCommit synchronization
2020-05-31 12:58:19.099 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Clearing transaction synchronization
2020-05-31 12:58:19.104 TRACE 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Triggering afterCompletion synchronization
2020-05-31 12:58:19.109 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.jdbc.datasource.ConnectionHolder#4905e3e7] for key [HikariDataSource (HikariPool-1)] from thread [http-nio-192.168.1.10-8080-exec-6]
2020-05-31 12:58:19.113 DEBUG 7194 --- [.10-8080-exec-6] o.s.orm.jpa.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
2020-05-31 12:59:07.063 TRACE 7194 --- [.10-8080-exec-6] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.orm.jpa.EntityManagerHolder#296e6024] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#1826475] from thread [http-nio-192.168.1.10-8080-exec-6]
EDIT2
I tried to remove the CrudRepository.save call, because it behaves strangely, creating a new transaction on its own, and seems responsible for previous one closing. The log becomes a little more logic, but still User.lastCommit new value doesn't get flushed.
2020-06-01 11:39:10.518 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder#5f0cca8f] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#27bbe773] bound to thread [http-nio-192.168.1.10-8080-exec-2]
2020-06-01 11:39:10.518 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(2096513672<open>)] for JPA transaction
2020-06-01 11:39:10.518 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [petmenu.services.users.UserCommitService.createFrom]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2020-06-01 11:39:10.518 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle#62cbdd03]
2020-06-01 11:39:10.519 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.jdbc.datasource.ConnectionHolder#4b988820] for key [HikariDataSource (HikariPool-1)] to thread [http-nio-192.168.1.10-8080-exec-2]
2020-06-01 11:39:10.519 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Initializing transaction synchronization
2020-06-01 11:39:10.519 TRACE 26420 --- [.10-8080-exec-2] o.s.t.i.TransactionInterceptor : Getting transaction for [petmenu.services.users.UserCommitService.createFrom]
2020-06-01 11:39:16.678 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder#5f0cca8f] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#27bbe773] bound to thread [http-nio-192.168.1.10-8080-exec-2]
2020-06-01 11:39:16.683 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(2096513672<open>)] for JPA transaction
2020-06-01 11:39:16.688 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder#4b988820] for key [HikariDataSource (HikariPool-1)] bound to thread [http-nio-192.168.1.10-8080-exec-2]
2020-06-01 11:39:16.693 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Participating in existing transaction
2020-06-01 11:39:16.697 TRACE 26420 --- [.10-8080-exec-2] o.s.t.i.TransactionInterceptor : Getting transaction for [petmenu.services.users.UserService.findUserById]
2020-06-01 11:39:16.720 TRACE 26420 --- [.10-8080-exec-2] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findUserById]: This method is not transactional.
2020-06-01 11:39:16.727 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.EntityManagerFactoryUtils : Opening JPA EntityManager
2020-06-01 11:39:16.733 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.orm.jpa.EntityManagerHolder#ca14c2f] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#161c9468] to thread [http-nio-192.168.1.10-8080-exec-2]
2020-06-01 11:39:16.738 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder#ca14c2f] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#161c9468] bound to thread [http-nio-192.168.1.10-8080-exec-2]
2020-06-01 11:39:16.747 DEBUG 26420 --- [.10-8080-exec-2] org.hibernate.SQL : select user0_.id as id1_0_, user0_.kc_id as kc_id2_0_, user0_.last_commit as last_com3_0_, user0_.name as name4_0_ from user user0_ where user0_.id=?
2020-06-01 11:39:16.754 TRACE 26420 --- [.10-8080-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [6]
2020-06-01 11:39:16.763 TRACE 26420 --- [.10-8080-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [INTEGER]) - [6]
2020-06-01 11:39:16.772 TRACE 26420 --- [.10-8080-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([kc_id2_0_] : [VARCHAR]) - [80a3b4b1-00d1-4062-a7e5-1927b938c203]
2020-06-01 11:39:16.779 TRACE 26420 --- [.10-8080-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([last_com3_0_] : [TIMESTAMP]) - [null]
2020-06-01 11:39:16.787 TRACE 26420 --- [.10-8080-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name4_0_] : [VARCHAR]) - [user1]
2020-06-01 11:39:16.795 TRACE 26420 --- [.10-8080-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [petmenu.services.users.UserService.findUserById]
2020-06-01 11:39:48.779 TRACE 26420 --- [.10-8080-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [petmenu.services.users.UserCommitService.createFrom]
2020-06-01 11:39:48.780 TRACE 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Triggering beforeCommit synchronization
2020-06-01 11:39:48.780 TRACE 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Triggering beforeCompletion synchronization
2020-06-01 11:39:48.780 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.orm.jpa.EntityManagerHolder#ca14c2f] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#161c9468] from thread [http-nio-192.168.1.10-8080-exec-2]
2020-06-01 11:39:48.782 INFO 26420 --- [.10-8080-exec-2] o.h.c.i.AbstractPersistentCollection : HHH000496: Detaching an uninitialized collection with queued operations from a session: [petmenu.entities.users.User.userCommitList#6]
2020-06-01 11:39:48.782 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2020-06-01 11:39:48.782 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(2096513672<open>)]
2020-06-01 11:39:48.787 TRACE 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Triggering afterCommit synchronization
2020-06-01 11:39:48.787 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Clearing transaction synchronization
2020-06-01 11:39:48.787 TRACE 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Triggering afterCompletion synchronization
2020-06-01 11:39:48.787 TRACE 26420 --- [.10-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.jdbc.datasource.ConnectionHolder#4b988820] for key [HikariDataSource (HikariPool-1)] from thread [http-nio-192.168.1.10-8080-exec-2]
2020-06-01 11:39:48.787 DEBUG 26420 --- [.10-8080-exec-2] o.s.orm.jpa.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
I spent just 4 days to realize the what the problem was. Awesome...(To be honest, I took advantage of all the stuff I had to read about JPA and Hibernate to get rid completely of OSIV).
When I defined my two datasources (Products and Users) configs, I annotated all the classes inside ProductsDataSourceConfiguration as #Primary, making them the default values when called without explicitly setting a name.
The problem was with PlatformTransactionManager in it, that was called as transaction manager for both my datasources, while actually being crafted just for Products one.
To solve the issue I had to specify the secondary transaction manager name on #Transactional annotation used on methods referring to secondary (Users) datasource:
#Transactional("usersTransactionManager")
#Service
public class UserCommitService {
...

Spring Data REST - Why hibernate fetches children entity with FetchType.LAZY?

I have a simple use case where I created 2 entities Account & AccountDetail.
These entities have a one-to-one relationship as shown below:
table relationship
The Account entity:
#Entity
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Setter
#Getter
#EqualsAndHashCode
public class Account {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
#OneToOne(mappedBy = "account", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private AccountDetail accountDetail;
}
The AccountDetail entity:
#Entity
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Setter
#Getter
#EqualsAndHashCode
public class AccountDetail {
#Id
private Long id;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) #MapsId
private Account account;
private String firstName;
private String lastName;
}
I am using Spring Boot (v2.3.0) with following dependencies:
- Spring Data JPA: to persist entities using Hibernate
- Rest Repositories: to expose repositories over REST endpoints
The issue is that Hibernate is fetching the AccountDetail entity even though I specified fetch = FetchType.LAZY.
You can see the 2 sql statements in the log:
hibernate log
What I already tried:
Using Projection:
#Projection(types = {Account.class})
public interface AccountProjection {
String getUsername();
}
With the following GET request http://localhost:8080/accounts/1?projection=accountProjection, I get:
{
"username": "warrior24",
"_links": {
"self": {
"href": "http://localhost:8080/accounts/1"
},
"account": {
"href": "http://localhost:8080/accounts/1{?projection}",
"templated": true
},
"accountDetail": {
"href": "http://localhost:8080/accounts/1/accountDetail"
}
}
}
Unfortunately, with this solution, it still makes 2 sql requests.
Using Hibernate Bytecode Enhancement with #LazyToOne(LazyToOneOption.NO_PROXY)
#OneToOne(mappedBy = "account", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#LazyToOne(LazyToOneOption.NO_PROXY)
private AccountDetail accountDetail;
Even this solution does not solve the issue.
Conclusion
I am not sure to understand why hibernate is fetching the child. At the moment it is not a big issue, but if the number of database records gets big it could impact on the performance.
Does anybody have a similar issue and maybe know how to solve it?
Update: Including the debug log for a GET request
2020-05-27 15:23:58.414 INFO 2119 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat-3].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-05-27 15:23:58.414 INFO 2119 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-05-27 15:23:58.414 DEBUG 2119 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2020-05-27 15:23:58.415 DEBUG 2119 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2020-05-27 15:23:58.415 INFO 2119 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2020-05-27 15:23:58.415 DEBUG 2119 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/accounts/1", parameters={}
2020-05-27 15:23:58.416 DEBUG 2119 --- [nio-8080-exec-1] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped to org.springframework.data.rest.webmvc.RepositoryEntityController#getItemResource(RootResourceInformation, Serializable, PersistentEntityResourceAssembler, HttpHeaders)
2020-05-27 15:23:58.416 DEBUG 2119 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2020-05-27 15:23:58.417 DEBUG 2119 --- [nio-8080-exec-1] stomAnnotationTransactionAttributeSource : Adding transactional method 'findById' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
2020-05-27 15:23:58.417 DEBUG 2119 --- [nio-8080-exec-1] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [SessionImpl(1137877934<open>)] for JPA transaction
2020-05-27 15:23:58.417 DEBUG 2119 --- [nio-8080-exec-1] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
2020-05-27 15:23:58.417 DEBUG 2119 --- [nio-8080-exec-1] o.s.jdbc.datasource.DataSourceUtils : Setting JDBC Connection [HikariProxyConnection#646683728 wrapping conn193: url=jdbc:h2:mem:f0df200a-97ea-4e5b-9f80-050ff9a550f7 user=SA] read-only
2020-05-27 15:23:58.417 DEBUG 2119 --- [nio-8080-exec-1] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle#3a65c273]
2020-05-27 15:23:58.417 DEBUG 2119 --- [nio-8080-exec-1] org.hibernate.SQL : select account0_.id as id1_0_0_, account0_.password as password2_0_0_, account0_.username as username3_0_0_ from account account0_ where account0_.id=?
2020-05-27 15:23:58.417 TRACE 2119 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2020-05-27 15:23:58.418 DEBUG 2119 --- [nio-8080-exec-1] org.hibernate.SQL : select accountdet0_.account_id as account_3_1_0_, accountdet0_.first_name as first_na1_1_0_, accountdet0_.last_name as last_nam2_1_0_ from account_detail accountdet0_ where accountdet0_.account_id=?
2020-05-27 15:23:58.418 TRACE 2119 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2020-05-27 15:23:58.418 DEBUG 2119 --- [nio-8080-exec-1] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2020-05-27 15:23:58.418 DEBUG 2119 --- [nio-8080-exec-1] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(1137877934<open>)]
2020-05-27 15:23:58.418 DEBUG 2119 --- [nio-8080-exec-1] o.s.jdbc.datasource.DataSourceUtils : Resetting read-only flag of JDBC Connection [HikariProxyConnection#646683728 wrapping conn193: url=jdbc:h2:mem:f0df200a-97ea-4e5b-9f80-050ff9a550f7 user=SA]
2020-05-27 15:23:58.418 DEBUG 2119 --- [nio-8080-exec-1] o.s.orm.jpa.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
2020-05-27 15:23:58.421 DEBUG 2119 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/hal+json', given [*/*] and supported [application/hal+json]
2020-05-27 15:23:58.421 DEBUG 2119 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [Resource { content: Account(id=1, username=warrior24, password=1234), links: [<http://localhost:8080 (truncated)...]
2020-05-27 15:23:58.421 DEBUG 2119 --- [nio-8080-exec-1] s.d.r.w.j.PersistentEntityJackson2Module : Serializing PersistentEntity org.springframework.data.jpa.mapping.JpaPersistentEntityImpl#45b7be72.
2020-05-27 15:23:58.423 DEBUG 2119 --- [nio-8080-exec-1] .s.ReloadableResourceBundleMessageSource : No properties file found for [classpath:rest-messages] - neither plain properties nor XML
2020-05-27 15:23:58.424 DEBUG 2119 --- [nio-8080-exec-1] .s.ReloadableResourceBundleMessageSource : No properties file found for [classpath:rest-messages_en] - neither plain properties nor XML
2020-05-27 15:23:58.424 DEBUG 2119 --- [nio-8080-exec-1] .s.ReloadableResourceBundleMessageSource : No properties file found for [classpath:rest-messages_en_GB] - neither plain properties nor XML
2020-05-27 15:23:58.426 DEBUG 2119 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2020-05-27 15:23:58.426 DEBUG 2119 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK
Try to use #JsonIgnore annotation that indicates that the annotated method or field is to be ignored by introspection-based serialization and deserialization functionality.
#JsonIgnore
#OneToOne(mappedBy = "account", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private AccountDetail accountDetail;
Try to put #EqualsAndHashCode.Exclude annotation to exclude accountDetail from equals and hashCode methods
#EqualsAndHashCode.Exclude
#OneToOne(mappedBy = "account", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private AccountDetail accountDetail;
SOLUTION (kind of)
Okay I think I found the solution but unfortunately it is not compatible with Spring Data Rest.
By adding optional = false, you can tell hibernate that you will ensure that the child reference will never be null (in my case AccountDetail).
Therefore, it will not need to fetch the child in order to check if it has to create a proxy or assign NULL.
#OneToOne(mappedBy = "account", fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
#LazyToOne(LazyToOneOption.NO_PROXY)
private AccountDetail accountDetail;
The issue with this solution is that you cannot create a new Account resource using the POST endpoint provided with the #RepositoryRestResource annotation.
Since, it now expects the AccountDetail to be not null, you need to provide the link of this resource in the JSON (which is not existing yet). And you cannot create the AccountDetail resource because it uses as primary key the foreign key from the Account table.

Spring-boot multiple databases - spring inserts data but only saves to one db

I've really been struggling with a multiple (2) db setup in springboot. I've spent countless of hours and followed many examples and I've read the complete documentation.
I find it hard to decide what should be added in my code because there are so many examples with different solutions around. There's Spring, Spring-boot, hibernate, jpa, beans, xml files, annotations, corrupt dependencies.
I've come up with a piece of code that doesn't give errors and saves my data. But, only the data to the primary database gets saved. The insert in the second db is happening according to the sql trace but no commit. What's going on here?
I also made a simple controller class to insert data with an http request, but it had the same results: only user in db1 gets saved, product in db2 doesn't.
If anybody has any clue it would be greatly appreciated. It's driving me nuts!
I realize this is just a simple piece of code, but it's test to see if I can use this approach in a bigger project.
Thanks!
the configuration:
import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import com.multidb.db1.enitities.User;
import com.multidb.db2.entities.Product;
import javax.sql.DataSource;
#EnableJpaRepositories
public class DbConfiguration {
#Bean
#Primary
#ConfigurationProperties("spring.datasource")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#Primary
#ConfigurationProperties("spring.datasource.configuration")
public HikariDataSource firstDataSource() {
return firstDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
#Bean
#ConfigurationProperties("spring.datasource2")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#ConfigurationProperties("spring.datasource2.configuration")
public BasicDataSource secondDataSource() {
return secondDataSourceProperties().initializeDataSourceBuilder()
.type(BasicDataSource.class).build();
}
//////
#Primary
#Bean
public LocalContainerEntityManagerFactoryBean userEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(firstDataSource())
.packages("db1")//User.class
.persistenceUnit("users")
.build();
}
#Bean
public LocalContainerEntityManagerFactoryBean productEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondDataSource())
.packages("db2")//Product.class
.persistenceUnit("products")
.build();
}
}
the applicaton.properties file
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.datasource.url=jdbc:mysql://localhost/db1?autoReconnect=true&useSSL=false
spring.datasource.username=user
spring.datasource.password=pass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.configuration.maximum-pool-size=30
spring.datasource2.url=jdbc:mysql://localhost/db2?autoReconnect=true&useSSL=false
spring.datasource2.username=user
spring.datasource2.password=pass
spring.datasource2.driver-class-name=com.mysql.jdbc.Driver
spring.datasource2.max-total=30
a simple user class
import javax.persistence.*;
#Entity
#Table
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public User() {
//
}
}
and the product class
import javax.persistence.*;
#Entity
#Table
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public Product() {
//
}
}
a user repo
import org.springframework.data.repository.CrudRepository;
import com.multidb.db1.enitities.User;
import org.springframework.transaction.annotation.Transactional;
#Transactional
public interface UserRepository extends CrudRepository<User, Long> {
//
}
a product repo
import com.multidb.db2.entities.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
public interface ProductRepository extends CrudRepository<Product, Long> {
//
}
a simple datainit class to write something to the db
import com.multidb.db1.repositories.UserRepository;
import com.multidb.db1.enitities.User;
import com.multidb.db2.entities.Product;
import com.multidb.db2.repositories.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
#Component
public class InitData implements ApplicationRunner {
#Autowired
private ProductRepository productRepository;
#Autowired
private UserRepository userRepository;
#Autowired
public InitData(){}
#Override
public void run(ApplicationArguments args) throws Exception {
addUser("Johnny", "Depp");
addProduct("Booze", 5.0);
}
private void addUser(String firstname, String lastname){
User user = new User(firstname, lastname);
userRepository.save(user);
}
private void addProduct(String name, double price){
Product product = new Product(name, price);
productRepository.save(product);
}
}
the Maven dependencies
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
Last but not least the ouput
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.3.RELEASE)
2019-04-02 13:20:09.084 INFO 47275 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2019-04-02 13:20:09.147 INFO 47275 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 56ms. Found 2 repository interfaces.
2019-04-02 13:20:09.466 INFO 47275 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$84774c02] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-04-02 13:20:09.765 INFO 47275 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-04-02 13:20:09.795 INFO 47275 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-04-02 13:20:09.796 INFO 47275 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.16]
2019-04-02 13:20:09.805 INFO 47275 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/Fdoe/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
2019-04-02 13:20:09.884 INFO 47275 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-04-02 13:20:09.885 INFO 47275 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1367 ms
2019-04-02 13:20:10.114 INFO 47275 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-04-02 13:20:10.327 INFO 47275 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-04-02 13:20:10.368 INFO 47275 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2019-04-02 13:20:10.423 INFO 47275 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.3.7.Final}
2019-04-02 13:20:10.424 INFO 47275 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2019-04-02 13:20:10.553 INFO 47275 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
2019-04-02 13:20:10.684 INFO 47275 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2019-04-02 13:20:11.209 DEBUG 47275 --- [ main] org.hibernate.SQL : drop table if exists hibernate_sequence
Hibernate: drop table if exists hibernate_sequence
2019-04-02 13:20:11.220 DEBUG 47275 --- [ main] org.hibernate.SQL : drop table if exists product
Hibernate: drop table if exists product
2019-04-02 13:20:11.222 DEBUG 47275 --- [ main] org.hibernate.SQL : drop table if exists user
Hibernate: drop table if exists user
2019-04-02 13:20:11.225 DEBUG 47275 --- [ main] org.hibernate.SQL : create table hibernate_sequence (next_val bigint) engine=MyISAM
Hibernate: create table hibernate_sequence (next_val bigint) engine=MyISAM
2019-04-02 13:20:11.228 DEBUG 47275 --- [ main] org.hibernate.SQL : insert into hibernate_sequence values ( 1 )
Hibernate: insert into hibernate_sequence values ( 1 )
2019-04-02 13:20:11.230 DEBUG 47275 --- [ main] org.hibernate.SQL : insert into hibernate_sequence values ( 1 )
Hibernate: insert into hibernate_sequence values ( 1 )
2019-04-02 13:20:11.231 DEBUG 47275 --- [ main] org.hibernate.SQL : create table product (id bigint not null, name varchar(255), price double precision not null, primary key (id)) engine=MyISAM
Hibernate: create table product (id bigint not null, name varchar(255), price double precision not null, primary key (id)) engine=MyISAM
2019-04-02 13:20:11.235 DEBUG 47275 --- [ main] org.hibernate.SQL : create table user (id bigint not null, first_name varchar(255), last_name varchar(255), primary key (id)) engine=MyISAM
Hibernate: create table user (id bigint not null, first_name varchar(255), last_name varchar(255), primary key (id)) engine=MyISAM
2019-04-02 13:20:11.239 INFO 47275 --- [ main] o.h.t.schema.internal.SchemaCreatorImpl : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl#3a7c678b'
2019-04-02 13:20:11.241 INFO 47275 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2019-04-02 13:20:11.651 INFO 47275 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-04-02 13:20:11.695 WARN 47275 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2019-04-02 13:20:11.889 INFO 47275 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-04-02 13:20:11.891 INFO 47275 --- [ main] com.fdoe.multidb.Application : Started Application in 3.92 seconds (JVM running for 4.308)
2019-04-02 13:20:11.913 DEBUG 47275 --- [ main] org.hibernate.SQL : select next_val as id_val from hibernate_sequence for update
Hibernate: select next_val as id_val from hibernate_sequence for update
2019-04-02 13:20:11.928 DEBUG 47275 --- [ main] org.hibernate.SQL : update hibernate_sequence set next_val= ? where next_val=?
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-02 13:20:11.948 DEBUG 47275 --- [ main] org.hibernate.SQL : insert into user (first_name, last_name, id) values (?, ?, ?)
Hibernate: insert into user (first_name, last_name, id) values (?, ?, ?)
2019-04-02 13:20:11.950 TRACE 47275 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Johnny]
2019-04-02 13:20:11.950 TRACE 47275 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [Depp]
2019-04-02 13:20:11.951 TRACE 47275 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [BIGINT] - [1]
2019-04-02 13:20:11.957 DEBUG 47275 --- [ main] org.hibernate.SQL : select next_val as id_val from hibernate_sequence for update
Hibernate: select next_val as id_val from hibernate_sequence for update
2019-04-02 13:20:11.958 DEBUG 47275 --- [ main] org.hibernate.SQL : update hibernate_sequence set next_val= ? where next_val=?
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-02 13:20:11.959 DEBUG 47275 --- [ main] org.hibernate.SQL : insert into product (name, price, id) values (?, ?, ?)
Hibernate: insert into product (name, price, id) values (?, ?, ?)
2019-04-02 13:20:11.959 TRACE 47275 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Booze]
2019-04-02 13:20:11.960 TRACE 47275 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [DOUBLE] - [5.0]
2019-04-02 13:20:11.960 TRACE 47275 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [BIGINT] - [2]
db1 - terminal/command line output
mysql> select * from user;
+----+------------+-----------+
| id | first_name | last_name |
+----+------------+-----------+
| 1 | Johnny | Depp |
+----+------------+-----------+
1 row in set (0.00 sec)
mysql>
db2 - terminal/command line output
mysql> select * from product;
Empty set (0.01 sec)
mysql>
You have not included Product Repository and User Repository class,please check the annotation in the class
Did you use Entity Manager
if Yes then
Did you use #PersistenceContext annotation for the entity manager
please follow the below example,try to run it on your local by just copy pasting the code and seeing the configuration
Spring Boot + JPA
if you have used CRUD Repository
You can refer to the below code
Spring Boot+CRUD Repository+JPA
Both are running in my local

Resources