Spring Data AWS DynamoDB Repository Find By Contains throws ClassCastException - java

I have an AWS DynamoDB Table called Group Table. It contains two fields ID and Members. The members field is a String Set. I would like to search the Group Table and return all Groups where the list of members contains a specified string.
When I attempt this using Spring Data's CRUD Repository FindByMembersContains, it returns a ClassCastException stating java.lang.String cannot be cast to java.util.Collection.
I have also attempted with a String List instead of String Set and get the same results.
I am using AWS Java SDK DynamoDB version 1.12.192 and Spring Data DynamoDB version 5.1.0.
I have no issues writing these entries or reading by ID using the repository.
Group.java
#DynamoDBTable(tableName = "GroupTable")
public class Group {
String id;
Set<String> members;
#DynamoDBHashKey
#DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDBAttribute
public Set<String> getMembers() {
return members;
}
public void setMembers(Set<String> members) {
this.members = members;
}
}
GroupRepository.java
#EnableScan
public interface GroupRepository extends CrudRepository<Group, String> {
List<Group> findByMembersContaining(String member);
}
GroupController.java
#RestController
#RequestMapping("/group")
public class GroupController {
private final GroupRepository groupRepository;
public GroupController(GroupRepository groupRepository) {
this.groupRepository = groupRepository;
}
#GetMapping("/test")
public List<Group> getTestGroups() {
String testMemberId = "SomeMemberId";
return groupRepository.findByMembersContaining(testMemberId);
}
}
DynamoDBConfig.java
#Configuration
#EnableDynamoDBRepositories(basePackages = "com.example.dynamodbtest.repository")
public class DynamoDBConfig {
#Value("${amazon.dynamodb.endpoint}")
private String amazonDynamoDBEndpoint;
#Value("${amazon.aws.accesskey}")
private String amazonAWSAccessKey;
#Value("${amazon.aws.secretkey}")
private String amazonAWSSecretKey;
private final ApplicationContext context;
public DynamoDBConfig(ApplicationContext context) {
this.context = context;
}
#Bean
public AmazonDynamoDB amazonDynamoDB() {
AmazonDynamoDB amazonDynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());
if (!ObjectUtils.isEmpty(amazonDynamoDBEndpoint)) {
amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
}
return amazonDynamoDB;
}
#Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
}
#Bean(name = "mvcHandlerMappingIntrospectorCustom")
public HandlerMappingIntrospector mvcHandlerMappingIntrospectorCustom() {
HandlerMappingIntrospector handlerMappingIntrospector = new HandlerMappingIntrospector();
handlerMappingIntrospector.setApplicationContext(context);
return handlerMappingIntrospector;
}
}
Stack Trace
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Collection
at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$Vector$ToSet$1.convert(StandardTypeConverters.java:449) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$DelegateConverter.convert(DynamoDBTypeConverter.java:104) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$NullSafeConverter.convert(DynamoDBTypeConverter.java:123) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$ExtendedConverter.convert(DynamoDBTypeConverter.java:83) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.convert(DynamoDBMapperFieldModel.java:138) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.getPropertyAttributeValue(AbstractDynamoDBQueryCriteria.java:499) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.createSingleValueCondition(AbstractDynamoDBQueryCriteria.java:648) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.withSingleValueCriteria(AbstractDynamoDBQueryCriteria.java:427) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.addCriteria(AbstractDynamoDBQueryCreator.java:103) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.create(AbstractDynamoDBQueryCreator.java:74) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.create(AbstractDynamoDBQueryCreator.java:42) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:119) ~[spring-data-commons-2.6.3.jar:2.6.3]
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95) ~[spring-data-commons-2.6.3.jar:2.6.3]
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:81) ~[spring-data-commons-2.6.3.jar:2.6.3]
at org.socialsignin.spring.data.dynamodb.repository.query.PartTreeDynamoDBQuery.doCreateQuery(PartTreeDynamoDBQuery.java:56) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.doCreateQueryWithPermissions(AbstractDynamoDBQuery.java:81) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery$CollectionExecution.execute(AbstractDynamoDBQuery.java:100) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.execute(AbstractDynamoDBQuery.java:311) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.3.jar:2.6.3]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.3.jar:2.6.3]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159) ~[spring-data-commons-2.6.3.jar:2.6.3]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.6.3.jar:2.6.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.18.jar:5.3.18]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.18.jar:5.3.18]
at com.sun.proxy.$Proxy69.findByMembersContaining(Unknown Source) ~[na:na]
at com.example.dynamodbtest.controller.GroupController.getTestGroups(GroupController.java:24) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.18.jar:5.3.18]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.18.jar:5.3.18]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.18.jar:5.3.18]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.60.jar:9.0.60]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.18.jar:5.3.18]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.18.jar:5.3.18]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.18.jar:5.3.18]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.60.jar:9.0.60]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.60.jar:9.0.60]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]
AWS DynamoDB Object
Group Object Showing String Set

Swapping to Enhanced Client, I was able to perform a 'Scan' with a 'Filter Expression' to return the results I want.
private DynamoDbClient getClient() {
Region region = Region.US_EAST_2;
return DynamoDbClient.builder()
.region(region)
.build();
}
private DynamoDbEnhancedClient getEnhancedClient() {
return DynamoDbEnhancedClient.builder()
.dynamoDbClient(getClient())
.build();
}
public List<Group> scanGroupsByMember(String memberId) {
DynamoDbTable<Group> groupTable = getEnhancedClient().table("GroupTable", TableSchema.fromClass(Group.class));
AttributeValue attributeValue = AttributeValue.builder()
.s(memberId)
.build();
Map<String, AttributeValue> expressionValues = new HashMap<>();
expressionValues.put(":value", attributeValue);
Expression expression = Expression.builder()
.expression("contains(members, :value)")
.expressionValues(expressionValues)
.build();
ScanEnhancedRequest scanEnhancedRequest = ScanEnhancedRequest.builder()
.filterExpression(expression)
.build();
return groupTable.scan(scanEnhancedRequest).items().stream().collect(Collectors.toList());
}

"I am using AWS Java SDK DynamoDB version 1.12.192".
You should use AWS SDK for Java V2 and to map Java classes to a DynamoDB table by using the Enhanced Client. This is best practice as opposed to using the old V1 API. See this doc topic:
Using the DynamoDB Enhanced Client in the AWS SDK for Java 2.x
Assume we have a Work table with a key named id. The following illustration shows the table.
TO map to this table, you can create a class that uses the #DynamoDbBean annotation like this:
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
#DynamoDbBean
public class Work {
private String id;
private String date;
private String description ;
private String guide;
private String username ;
private String status ;
private String archive ;
#DynamoDbPartitionKey
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDbSortKey
public String getName() {
return this.username;
}
public void setArchive(String archive) {
this.archive = archive;
}
public String getArchive() {
return this.archive;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatus() {
return this.status;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return this.username;
}
public void setGuide(String guide) {
this.guide = guide;
}
public String getGuide() {
return this.guide;
}
public String getDate() {
return this.date;
}
public void setDate(String date) {
this.date = date;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
To use the Enhanced Client to perform CRUD operation, create a DynamoDbTable object.
// Create a DynamoDbEnhancedClient.
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(getClient())
.build();
// Create a DynamoDbTable object.
DynamoDbTable<Work> workTable = enhancedClient.table("Work", TableSchema.fromBean(Work.class));
Now you can perform CRUD operations. To place a record into the table, you can create a Work object and set the data. Then call the DynamoDbTable objects putItem method.
// Populate the table.
Work record = new Work();
record.setUsername(item.getName());
record.setId(myGuid);
record.setDescription(item.getDescription());
record.setDate(now()) ;
record.setStatus(item.getStatus());
record.setArchive("Open");
record.setGuide(item.getGuide());
// Put the customer data into a DynamoDB table.
workTable.putItem(record);
The Amazon DynamoDB API V2 (Including the Enhanced Client) can be used within a Spring BOOT app too. To learn How TO build a SAMPLE Spring Boot web App, see this AWS tutorial.

Related

I get "Cannot add or update a child row: a foreign key constraint fails" for some reason

I am trying to implement a rezervation of a table.
A page has a combo-box of tables and input fields. I choose a table, pick a date, enter a number of customers and press Proceed. Then it sends me to a page with input fields. I input information about a customer and add him to the list. I can also add more customers. If it's enough, I press Reserve.
It's supposed to show a page telling me that it was successful, but instead I get:
java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`mydb`.`Upis`, CONSTRAINT `fk_Upis_Musterija1` FOREIGN KEY (`idMusterija`) REFERENCES `Musterija` (`idMusterija`))
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-4.0.3.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.3.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3375) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3908) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:344) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1407) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:489) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3290) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2425) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:449) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562) ~[spring-orm-5.3.21.jar:5.3.21]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) ~[spring-tx-5.3.21.jar:5.3.21]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.3.21.jar:5.3.21]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654) ~[spring-tx-5.3.21.jar:5.3.21]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407) ~[spring-tx-5.3.21.jar:5.3.21]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174) ~[spring-data-jpa-2.7.1.jar:2.7.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.21.jar:5.3.21]
at jdk.proxy8/jdk.proxy8.$Proxy170.save(Unknown Source) ~[na:na]
at com.example.demo.controller.RezervacijaController.rezervisi(RezervacijaController.java:92) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.21.jar:5.3.21]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.64.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.21.jar:5.3.21]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.64.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1787) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
SQL scripts and tables:
CREATE TABLE `Musterija` (
`idMusterija` int NOT NULL AUTO_INCREMENT,
`ime` varchar(20) NOT NULL,
`prezime` varchar(50) NOT NULL,
`adresa` varchar(100) NOT NULL,
`email` varchar(200) NOT NULL,
`brTelefona` varchar(20) NOT NULL,
PRIMARY KEY (`idMusterija`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
CREATE TABLE `Upis` (
`idRezervacija` int NOT NULL,
`idMusterija` int NOT NULL,
KEY `fk_Upis_Musterija1_idx` (`idMusterija`),
KEY `fk_Upis_Rezervacija1_idx` (`idRezervacija`),
CONSTRAINT `fk_Upis_Musterija1` FOREIGN KEY (`idMusterija`) REFERENCES `Musterija` (`idMusterija`),
CONSTRAINT `fk_Upis_Rezervacija1` FOREIGN KEY (`idRezervacija`) REFERENCES `Rezervacija` (`idRezervacija`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
CREATE TABLE `Rezervacija` (
`idRezervacija` int NOT NULL AUTO_INCREMENT,
`brMusterija` int NOT NULL,
`datumRezervacije` datetime NOT NULL,
`cenaRezervacije` double NOT NULL,
`idSto` int NOT NULL,
`idUser` int NOT NULL,
PRIMARY KEY (`idRezervacija`),
KEY `fk_Rezervacija_Sto1_idx` (`idSto`),
KEY `fk_Rezervacija_User1_idx` (`idUser`),
CONSTRAINT `fk_Rezervacija_Sto1` FOREIGN KEY (`idSto`) REFERENCES `Sto` (`idSto`),
CONSTRAINT `fk_Rezervacija_User1` FOREIGN KEY (`idUser`) REFERENCES `User` (`idUser`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
Rezervacija.java:
#Entity
#NamedQuery(name="Rezervacija.findAll", query="SELECT r FROM Rezervacija r")
public class Rezervacija implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int idRezervacija;
private int brMusterija;
private double cenaRezervacije;
#Temporal(TemporalType.TIMESTAMP)
private Date datumRezervacije;
//bi-directional many-to-many association to Musterija
#ManyToMany
#JoinTable(
name="Upis"
, joinColumns={
#JoinColumn(name="idRezervacija")
}
, inverseJoinColumns={
#JoinColumn(name="idMusterija")
}
)
private List<Musterija> musterijas;
//bi-directional many-to-one association to Sto
#ManyToOne
#JoinColumn(name="idSto")
private Sto sto;
//bi-directional many-to-one association to User
#ManyToOne
#JoinColumn(name="idUser")
private User user;
//bi-directional many-to-one association to Upis
#OneToMany(mappedBy="rezervacija")
private List<Upis> upis;
public Rezervacija() {
}
public int getIdRezervacija() {
return this.idRezervacija;
}
public void setIdRezervacija(int idRezervacija) {
this.idRezervacija = idRezervacija;
}
public int getBrMusterija() {
return this.brMusterija;
}
public void setBrMusterija(int brMusterija) {
this.brMusterija = brMusterija;
}
public double getCenaRezervacije() {
return this.cenaRezervacije;
}
public void setCenaRezervacije(double cenaRezervacije) {
this.cenaRezervacije = cenaRezervacije;
}
public Date getDatumRezervacije() {
return this.datumRezervacije;
}
public void setDatumRezervacije(Date datumRezervacije) {
this.datumRezervacije = datumRezervacije;
}
public List<Musterija> getMusterijas() {
return this.musterijas;
}
public void setMusterijas(List<Musterija> musterijas) {
this.musterijas = musterijas;
}
public Sto getSto() {
return this.sto;
}
public void setSto(Sto sto) {
this.sto = sto;
}
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
public List<Upis> getUpis() {
return this.upis;
}
public void setUpis(List<Upis> upis) {
this.upis = upis;
}
public Upis addUpi(Upis upi) {
getUpis().add(upi);
upi.setRezervacija(this);
return upi;
}
public Upis removeUpi(Upis upi) {
getUpis().remove(upi);
upi.setRezervacija(null);
return upi;
}
}
Sto.java:
#Entity
#NamedQuery(name="Sto.findAll", query="SELECT s FROM Sto s")
public class Sto implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int idSto;
private int brMesta;
//bi-directional many-to-one association to Rezervacija
#OneToMany(mappedBy="sto")
private List<Rezervacija> rezervacijas;
public Sto() {
}
public int getIdSto() {
return this.idSto;
}
public void setIdSto(int idSto) {
this.idSto = idSto;
}
public int getBrMesta() {
return this.brMesta;
}
public void setBrMesta(int brMesta) {
this.brMesta = brMesta;
}
public List<Rezervacija> getRezervacijas() {
return this.rezervacijas;
}
public void setRezervacijas(List<Rezervacija> rezervacijas) {
this.rezervacijas = rezervacijas;
}
public Rezervacija addRezervacija(Rezervacija rezervacija) {
getRezervacijas().add(rezervacija);
rezervacija.setSto(this);
return rezervacija;
}
public Rezervacija removeRezervacija(Rezervacija rezervacija) {
getRezervacijas().remove(rezervacija);
rezervacija.setSto(null);
return rezervacija;
}
}
Upis.java:
#Entity
#NamedQuery(name="Upis.findAll", query="SELECT u FROM Upis u")
public class Upis implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private UpisPK id;
//bi-directional many-to-one association to Musterija
#ManyToOne
#JoinColumn(name="idMusterija", insertable = false, updatable = false)
private Musterija musterija;
//bi-directional many-to-one association to Rezervacija
#ManyToOne
#JoinColumn(name="idRezervacija", insertable = false, updatable = false)
private Rezervacija rezervacija;
public Upis() {
}
public UpisPK getId() {
return this.id;
}
public void setId(UpisPK id) {
this.id = id;
}
public Musterija getMusterija() {
return this.musterija;
}
public void setMusterija(Musterija musterija) {
this.musterija = musterija;
}
public Rezervacija getRezervacija() {
return this.rezervacija;
}
public void setRezervacija(Rezervacija rezervacija) {
this.rezervacija = rezervacija;
}
}
UpisPK.java:
#Embeddable
public class UpisPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#Column(insertable=false, updatable=false)
private int idRezervacija;
#Column(insertable=false, updatable=false)
private int idMusterija;
public UpisPK() {
}
public int getIdRezervacija() {
return this.idRezervacija;
}
public void setIdRezervacija(int idRezervacija) {
this.idRezervacija = idRezervacija;
}
public int getIdMusterija() {
return this.idMusterija;
}
public void setIdMusterija(int idMusterija) {
this.idMusterija = idMusterija;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof UpisPK)) {
return false;
}
UpisPK castOther = (UpisPK)other;
return
(this.idRezervacija == castOther.idRezervacija)
&& (this.idMusterija == castOther.idMusterija);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + this.idRezervacija;
hash = hash * prime + this.idMusterija;
return hash;
}
}
Musterija.java:
#Entity
#NamedQuery(name="Musterija.findAll", query="SELECT m FROM Musterija m")
public class Musterija implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int idMusterija;
private String adresa;
private String brTelefona;
private String email;
private String ime;
private String prezime;
//bi-directional many-to-one association to Narudzbina
#OneToMany(mappedBy="musterija")
private List<Narudzbina> narudzbinas;
//bi-directional many-to-many association to Rezervacija
#ManyToMany(mappedBy="musterijas")
private List<Rezervacija> rezervacijas;
//bi-directional many-to-one association to Upis
#OneToMany(mappedBy="musterija")
private List<Upis> upis;
public Musterija() {
}
public int getIdMusterija() {
return this.idMusterija;
}
public void setIdMusterija(int idMusterija) {
this.idMusterija = idMusterija;
}
public String getAdresa() {
return this.adresa;
}
public void setAdresa(String adresa) {
this.adresa = adresa;
}
public String getBrTelefona() {
return this.brTelefona;
}
public void setBrTelefona(String brTelefona) {
this.brTelefona = brTelefona;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getIme() {
return this.ime;
}
public void setIme(String ime) {
this.ime = ime;
}
public String getPrezime() {
return this.prezime;
}
public void setPrezime(String prezime) {
this.prezime = prezime;
}
public List<Narudzbina> getNarudzbinas() {
return this.narudzbinas;
}
public void setNarudzbinas(List<Narudzbina> narudzbinas) {
this.narudzbinas = narudzbinas;
}
public Narudzbina addNarudzbina(Narudzbina narudzbina) {
getNarudzbinas().add(narudzbina);
narudzbina.setMusterija(this);
return narudzbina;
}
public Narudzbina removeNarudzbina(Narudzbina narudzbina) {
getNarudzbinas().remove(narudzbina);
narudzbina.setMusterija(null);
return narudzbina;
}
public List<Rezervacija> getRezervacijas() {
return this.rezervacijas;
}
public void setRezervacijas(List<Rezervacija> rezervacijas) {
this.rezervacijas = rezervacijas;
}
public List<Upis> getUpis() {
return this.upis;
}
public void setUpis(List<Upis> upis) {
this.upis = upis;
}
public Upis addUpi(Upis upi) {
getUpis().add(upi);
upi.setMusterija(this);
return upi;
}
public Upis removeUpi(Upis upi) {
getUpis().remove(upi);
upi.setMusterija(null);
return upi;
}
}
RezervacijaController.java:
#Controller
#RequestMapping("/rezervacije")
public class RezervacijaController {
#Autowired
RezervacijaRepository rr;
#Autowired
MusterijaRepository mr;
#Autowired
StoRepository sr;
#Autowired
UpisRepository ur;
#GetMapping(value = "popuniStolove")
public String popuniStolove(HttpServletRequest request) {
List<Sto> stolovi = sr.findAll();
request.setAttribute("stolovi", stolovi);
return "rezervacijaStola";
}
#PostMapping(value = "unesiRezervaciju")
public String unesiRezervaciju(Integer brMusterija, Date datum, Sto sto, HttpServletRequest request) {
Rezervacija r = new Rezervacija();
r.setBrMusterija(brMusterija);
r.setCenaRezervacije(800.0 * brMusterija);
r.setDatumRezervacije(datum);
sto.addRezervacija(r);
sr.updateSto(sto);
List<Musterija> musterije = new ArrayList<Musterija>();
request.getSession().setAttribute("musterije", musterije);
request.getSession().setAttribute("rezervacija", r);
return "unosMusterija";
}
#SuppressWarnings("unchecked")
#PostMapping(value = "/dodajMusteriju")
public String dodajMusteriju(String ime, String prezime, String adresa, String email, String brTelefona, HttpServletRequest request) {
List<Musterija> musterije = (ArrayList<Musterija>) request.getSession().getAttribute("musterije");
Musterija m = new Musterija();
m.setIme(ime);
m.setPrezime(prezime);
m.setAdresa(adresa);
m.setEmail(email);
m.setBrTelefona(brTelefona);
musterije.add(m);
request.setAttribute("musterije", musterije);
return "unosMusterija";
}
#SuppressWarnings("unchecked")
#PostMapping(value = "rezervisi")
public String rezervisi(HttpServletRequest request) {
Rezervacija r = (Rezervacija) request.getSession().getAttribute("rezervacija");
List<Musterija> musterije = (ArrayList<Musterija>) request.getSession().getAttribute("musterije");
for (Musterija m : musterije) {
Upis upis = new Upis();
UpisPK uPK = new UpisPK();
uPK.setIdMusterija(m.getIdMusterija());
uPK.setIdRezervacija(r.getIdRezervacija());
upis.setId(uPK);
ur.save(upis);
mr.save(m);
}
rr.save(r);
return "uspehRezervacija";
}
#InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(true);
binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
}
}
Repositories:
public interface UpisRepository extends JpaRepository<Upis, UpisPK> {
}
#Repository
#Transactional
public class StoRepoSpecificImpl implements StoRepoSpecific {
#PersistenceContext
EntityManager em;
#Override
public void updateSto(Sto sto) {
try {
em.merge(sto);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public interface StoRepoSpecific {
public void updateSto(Sto sto);
}
public interface StoRepository extends JpaRepository<Sto, Integer>, StoRepoSpecific {
}
You can see my public project on Github.

Spring Boot, Failed to lazily initialize a collection of role, could not initialize proxy - no Session

I am making a website in which I am trying to order ingredients. I choose and ingredient and enter its quantity, then I click add. I repeat it few times. Then I go to the next page, in which I chose a supplier. Then I press "Order".
It is expected to insert Nabavka into the database and open a page saying that the order was successful, but instead I get an Exception telling me that I can't initialize it lazily.
From NabavkaController.java:
#Autowired
NamirnicaRepository namr;
#Autowired
NabavkaRepository nabr;
#Autowired
DobavljacRepository dr;
#Autowired
NabavkaKorpaRepository nkr;...
#SuppressWarnings("unchecked")
#PostMapping(value = "sacuvajNabavku")
public String sacuvajNabavku(Dobavljac dobavljac, HttpServletRequest request) {
List<Namirnica> izabrane = (ArrayList<Namirnica>) request.getSession()
.getAttribute("izabrane");
List<Integer> brojevi = (ArrayList<Integer>) request.getSession()
.getAttribute("brojevi");
Nabavka n = new Nabavka();
for (int i = 0; i < izabrane.size(); i++) {
System.out.println(izabrane.get(i).getNaziv());
NabavkaKorpaPK nkPK = new NabavkaKorpaPK();
nkPK.setIdNabavka(n.getIdNabavka());
nkPK.setIdNamirnica(izabrane.get(i).getIdNamirnica());
NabavkaKorpa nk = new NabavkaKorpa();
nk.setId(nkPK);
nk.setKolicina(brojevi.get(i));
nk.setUkupnaCena(izabrane.get(i).getCenaNamirnice() * brojevi.get(0));
izabrane.get(i).addNabavkaKorpa(nk);
n.addNabavkaKorpa(nk);
nabr.updateNamirnica(izabrane.get(i));
}
n.setDatumNabavke(new Date());
n.setUkupnaCena(n.getNabavkaKorpas().stream().map(k -> k.getUkupnaCena()).reduce(0.0,
(a, b) -> a + b));
n.setDobavljac(dobavljac);
dobavljac.addNabavka(n);
nabr.save(n);
return "uspehNabavka";
}
Nabavka.java:
#Entity
#NamedQuery(name="Nabavka.findAll", query="SELECT n FROM Nabavka n")
public class Nabavka implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int idNabavka;
#Temporal(TemporalType.TIMESTAMP)
private Date datumNabavke;
private double ukupnaCena;
//bi-directional many-to-one association to Dobavljac
#ManyToOne
#JoinColumn(name="idDobavljac")
private Dobavljac dobavljac;
//bi-directional many-to-one association to Menadzer
#ManyToOne
#JoinColumns({
#JoinColumn(name="idMenadzer", referencedColumnName="idMenadzer"),
#JoinColumn(name="idRadnik", referencedColumnName="idRadnik")
})
private Menadzer menadzer;
//bi-directional many-to-one association to User
#ManyToOne
#JoinColumn(name="idUser")
private User user;
//bi-directional many-to-one association to NabavkaKorpa
#OneToMany(mappedBy="nabavka", cascade={CascadeType.ALL})
private List<NabavkaKorpa> nabavkaKorpas = new ArrayList<NabavkaKorpa>();
public Nabavka() {
}
public int getIdNabavka() {
return this.idNabavka;
}
public void setIdNabavka(int idNabavka) {
this.idNabavka = idNabavka;
}
public Date getDatumNabavke() {
return this.datumNabavke;
}
public void setDatumNabavke(Date datumNabavke) {
this.datumNabavke = datumNabavke;
}
public double getUkupnaCena() {
return this.ukupnaCena;
}
public void setUkupnaCena(double ukupnaCena) {
this.ukupnaCena = ukupnaCena;
}
public Dobavljac getDobavljac() {
return this.dobavljac;
}
public void setDobavljac(Dobavljac dobavljac) {
this.dobavljac = dobavljac;
}
public Menadzer getMenadzer() {
return this.menadzer;
}
public void setMenadzer(Menadzer menadzer) {
this.menadzer = menadzer;
}
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
public List<NabavkaKorpa> getNabavkaKorpas() {
return this.nabavkaKorpas;
}
public void setNabavkaKorpas(List<NabavkaKorpa> nabavkaKorpas) {
this.nabavkaKorpas = nabavkaKorpas;
}
public NabavkaKorpa addNabavkaKorpa(NabavkaKorpa nabavkaKorpa) {
getNabavkaKorpas().add(nabavkaKorpa);
nabavkaKorpa.setNabavka(this);
return nabavkaKorpa;
}
public NabavkaKorpa removeNabavkaKorpa(NabavkaKorpa nabavkaKorpa) {
getNabavkaKorpas().remove(nabavkaKorpa);
nabavkaKorpa.setNabavka(null);
return nabavkaKorpa;
}
}
Namirnica.java:
#Entity
#NamedQuery(name="Namirnica.findAll", query="SELECT n FROM Namirnica n")
public class Namirnica implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int idNamirnica;
private double cenaNamirnice;
private String kolicina;
private String naziv;
private int stanje;
//bi-directional many-to-one association to NabavkaKorpa
#OneToMany(mappedBy="namirnica")
private List<NabavkaKorpa> nabavkaKorpas = new ArrayList<NabavkaKorpa>();
public Namirnica() {
}
public int getIdNamirnica() {
return this.idNamirnica;
}
public void setIdNamirnica(int idNamirnica) {
this.idNamirnica = idNamirnica;
}
public double getCenaNamirnice() {
return this.cenaNamirnice;
}
public void setCenaNamirnice(double cenaNamirnice) {
this.cenaNamirnice = cenaNamirnice;
}
public String getKolicina() {
return this.kolicina;
}
public void setKolicina(String kolicina) {
this.kolicina = kolicina;
}
public String getNaziv() {
return this.naziv;
}
public void setNaziv(String naziv) {
this.naziv = naziv;
}
public int getStanje() {
return this.stanje;
}
public void setStanje(int stanje) {
this.stanje = stanje;
}
public List<NabavkaKorpa> getNabavkaKorpas() {
return this.nabavkaKorpas;
}
public void setNabavkaKorpas(List<NabavkaKorpa> nabavkaKorpas) {
this.nabavkaKorpas = nabavkaKorpas;
}
public NabavkaKorpa addNabavkaKorpa(NabavkaKorpa nabavkaKorpa) {
getNabavkaKorpas().add(nabavkaKorpa);
nabavkaKorpa.setNamirnica(this);
return nabavkaKorpa;
}
public NabavkaKorpa removeNabavkaKorpa(NabavkaKorpa nabavkaKorpa) {
getNabavkaKorpas().remove(nabavkaKorpa);
nabavkaKorpa.setNamirnica(null);
return nabavkaKorpa;
}
}
NabavkaKorpa.java:
#Entity
#NamedQuery(name="NabavkaKorpa.findAll", query="SELECT n FROM NabavkaKorpa n")
public class NabavkaKorpa implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private NabavkaKorpaPK id;
private int kolicina;
private double ukupnaCena;
//bi-directional many-to-one association to Nabavka
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name="idNabavka", insertable = false, updatable = false)
private Nabavka nabavka;
//bi-directional many-to-one association to Namirnica
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name="idNamirnica", insertable = false, updatable = false)
private Namirnica namirnica;
public NabavkaKorpa() {
}
public NabavkaKorpaPK getId() {
return this.id;
}
public void setId(NabavkaKorpaPK id) {
this.id = id;
}
public int getKolicina() {
return this.kolicina;
}
public void setKolicina(int kolicina) {
this.kolicina = kolicina;
}
public double getUkupnaCena() {
return this.ukupnaCena;
}
public void setUkupnaCena(double ukupnaCena) {
this.ukupnaCena = ukupnaCena;
}
public Nabavka getNabavka() {
return this.nabavka;
}
public void setNabavka(Nabavka nabavka) {
this.nabavka = nabavka;
}
public Namirnica getNamirnica() {
return this.namirnica;
}
public void setNamirnica(Namirnica namirnica) {
this.namirnica = namirnica;
}
}
NabavkaKorpaPK.java:
#Embeddable
public class NabavkaKorpaPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#Column(insertable=false, updatable=false)
private int idNamirnica;
#Column(insertable=false, updatable=false)
private int idNabavka;
public NabavkaKorpaPK() {
}
public int getIdNamirnica() {
return this.idNamirnica;
}
public void setIdNamirnica(int idNamirnica) {
this.idNamirnica = idNamirnica;
}
public int getIdNabavka() {
return this.idNabavka;
}
public void setIdNabavka(int idNabavka) {
this.idNabavka = idNabavka;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof NabavkaKorpaPK)) {
return false;
}
NabavkaKorpaPK castOther = (NabavkaKorpaPK)other;
return
(this.idNamirnica == castOther.idNamirnica)
&& (this.idNabavka == castOther.idNabavka);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + this.idNamirnica;
hash = hash * prime + this.idNabavka;
return hash;
}
}
NabavkaKorpaRepository.java:
public interface NabavkaKorpaRepository extends JpaRepository<NabavkaKorpa, NabavkaKorpaPK> {
}
NabavkaRepository.java:
public interface NabavkaRepository extends JpaRepository<Nabavka, Integer>, NabavkaRepoSpecific {
}
NabavkaRepoSpeicific.java
public interface NabavkaRepoSpecific {
public void updateNamirnica(Namirnica namirnica);
}
NabavkaRepoSpecificImpl.java:
#Repository
#Transactional
public class NabavkaRepoSpecificImpl implements NabavkaRepoSpecific {
#PersistenceContext
EntityManager em;
#Override
public void updateNamirnica(Namirnica namirnica) {
try {
em.merge(namirnica);
} catch (Exception e) {
e.printStackTrace();
}
}
}
NamirnicaRepository.java:
public interface NamirnicaRepository extends JpaRepository<Namirnica, Integer> {
}
Exception:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: model.Namirnica.nabavkaKorpas, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:614) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:591) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.write(AbstractPersistentCollection.java:415) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at org.hibernate.collection.internal.PersistentBag.add(PersistentBag.java:407) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final]
at model.Namirnica.addNabavkaKorpa(Namirnica.java:85) ~[classes/:na]
at com.example.demo.controller.NabavkaController.sacuvajNabavku(NabavkaController.java:95) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.21.jar:5.3.21]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.64.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.21.jar:5.3.21]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.64.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1787) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.64.jar:9.0.64]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
EDIT: I get Namirnicas from a session. Here's the GitHub link.
The cause of an error that you get a list List<Namirnica> izabrane at one step (lets name it A) of the flow, but work with Namirinica items at the second step(B).
This list is lazy by default. It means that you can access it at A point only (when #Transaction/Persistent Context/Hibernate Session is open).
#OneToMany(mappedBy="namirnica")
private List<NabavkaKorpa> nabavkaKorpas = new ArrayList<NabavkaKorpa>();
Even opening a new transaction at the B point will not help, because it will be another Persistent context/Hibernate session (not the same as in the A point).
You can try to make nabavkaKorpas EAGER, probably it will help.
But you have a design problem.
Common rule
Never work with an associated collection from the #OneToMany part.
How to fix
You have to save a new NabavkaKorpa, not Namirnica.
NabavkaKorpa nabavka = new NabavkaKorpa();
nabavka.setNamirnica(namirnica);
nabavkaKorpaRepositiry.save(nabavka);
You don't even need Namirnica to do it.
For Hibernate
Namirnica namirnica= new Namirnica();
namirnica.setId(namirnicaId);
NabavkaKorpa nabavka = new NabavkaKorpa();
nabavka.setNamirnica(namirnica);
nabavkaKorpaRepositiry.save(nabavka);
For Spring Data (to not having additional query to get Namirnica from a database)
Namirnica namirnica= namirinicaRepositiry.getOne(namirnicaId);
NabavkaKorpa nabavka = new NabavkaKorpa();
nabavka.setNamirnica(namirnica);
nabavkaKorpaRepositiry.save(nabavka);
Notes about Persistent Context
When you use #Transactional annotation on the method, there is not only an open transaction inside that method, but also opened Persistent Context/Hibernate Session. So such #Transactional approach that using widely in Spring is a bit confused.
When Persistent Context is open, Hibernate observe all changes that are made for persistent objects, like Namirnica and NabavkaKorpa, and try to save them to the database, so you even don't need to call save() method of a repository (but I prefer to explicitly call it).
So in such situation you, probably, can keep association in the valid state from two sides: Namirnica has NabavkaKorpa in the list and NabavkaKorpa refers to Namirnica. But usually I don't keep such things.
When Persistent Context is closed, Hibernate doesn't observe changes and you don't have to keep associations in the valid state. When you call a repository method, for each such call a separate Persistent Context is created. And all such calls are independent from the Hibernate point of view. You can enable SQL logging and see what happens.
So you don't need to do
izabrane.get(i).addNabavkaKorpa(nk);
Just work with NabavkaKorpa.
Notes
It is a very bad idea having CascadeType.ALL here.
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name="idNamirnica", insertable = false, updatable = false)
private Namirnica namirnica;

Having an issue with One To Many and Many To One spring jpa app. getting a class cannot be serialized error

I am having an issue with a bidirectional mapping. and when I try to post or get I get a error class site cant be serialized. if I take away the mappedby in the site then it works just fine and take always the site field in the inventory it will work is that the right way?
11:24:52.341 [main] INFO - in 3.977 seconds (JVM running for 4.471)
11:25:36.453 [http-nio-8080-exec-2] INFO com.cbcse.controller.SiteController - I Fell in here
11:25:36.533 [http-nio-8080-exec-2] WARN com.cbcse.service.SiteServiceImpl - Handling of [org.springframework.transaction.TransactionSystemException] resulted in Exception
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:571)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy2/jdk.proxy2.$Proxy107.save(Unknown Source)
at com.cbcse.service.SiteServiceImpl.add(SiteServiceImpl.java:71)
at com.cbcse.controller.SiteController.add(SiteController.java:53)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562)
... 66 common frames omitted
Caused by: java.lang.ClassCastException: class com.cbcse.entity.Site cannot be cast to class java.io.Serializable (com.cbcse.entity.Site is in unnamed module of loader 'app'; java.io.Serializable is in module java.base of loader 'bootstrap')
at org.hibernate.type.CollectionType.getKeyOfOwner(CollectionType.java:446)
at org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:166)
at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:53)
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:183)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:229)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:93)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1416)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:507)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3299)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2434)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:449)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
... 67 common frames omitted
#Entity
public class Site {
#Id
#GeneratedValue
Long id;
String name;
String date;
String suite;
String unit;
long siteId;
#OneToMany( mappedBy="sites", fetch = FetchType.LAZY ,cascade = {CascadeType.MERGE,CascadeType.REFRESH},orphanRemoval = true)
List<Inventory> inventory = new ArrayList<>();
// #OneToMany(fetch = FetchType.LAZY ,cascade = CascadeType.ALL,orphanRemoval = true)
// List<SiteFiles> siteFiles = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSiteName() {
return name;
}
public void setSiteName(String name) {
this.name = name;
}
public String getSiteDate() {
return date;
}
public void setSiteDate(String date) {
this.date = date;
}
public String getSiteSuite() {
return suite;
}
public void setSiteSuite(String suite) {
this.suite = suite;
}
public String getSiteUnit() {
return unit;
}
public void setSiteUnit(String unit) {
this.unit = unit;
}
public Long getSiteId() {
return siteId;
}
public void setSiteId(Long siteId) {
this.siteId = siteId;
}
public List<Inventory> getInventory() {
return inventory;
}
public void setInventory(List<Inventory> inventory) {
this.inventory = inventory;
}
}
#Entity
public class Inventory {
#Id
#GeneratedValue
Long id;
Long parentId;
#ManyToOne(fetch = FetchType.LAZY ,cascade = {CascadeType.MERGE,CascadeType.REFRESH})
#JoinColumn(name = "parentId", referencedColumnName = "siteId",insertable= false, updatable= false)
private Site sites;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Site getSites() {
return sites;
}
public void setSites(Site sites) {
this.sites = sites;
}
}

Spring Data JPA : DataIntegrityViolationException

I have three entities Blog, Comments, ParentChildComment.
Comment is mapped using ManyToOne relationship to Blog.
ParentChildComment has two columns to store id value of parent_comment and child_comment (this is done to store the info regarding which comment is a reply to another one) and both these columns are mapped using OneToOne relationship to Comment table which I guess is the sourcee of problem.
PROBLEM
When deleting a blog, comments are deleted due to cascade delete, but the parent_child table is still referncing to table comments which throw error org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [fkf3i44d11sgikshmo17q4fq1a4]; nested exception is org.hibernate.exception.ConstraintViolationException
The whole trace :
SQL Error: 0, SQLState: 23503
2021-05-19 22:31:07.123 ERROR 16445 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: update or delete on table "comments" violates foreign key constraint "fkf3i44d11sgikshmo17q4fq1a4" on table "parent_child_comment"
Detail: Key (id)=(4) is still referenced from table "parent_child_comment".
2021-05-19 22:31:07.124 INFO 16445 --- [nio-8080-exec-6] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2021-05-19 22:31:07.133 ERROR 16445 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [fkf3i44d11sgikshmo17q4fq1a4]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
org.postgresql.util.PSQLException: ERROR: update or delete on table "comments" violates foreign key constraint "fkf3i44d11sgikshmo17q4fq1a4" on table "parent_child_comment"
Detail: Key (id)=(4) is still referenced from table "parent_child_comment".
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2553) ~[postgresql-42.2.19.jar:42.2.19]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2285) ~[postgresql-42.2.19.jar:42.2.19]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:323) ~[postgresql-42.2.19.jar:42.2.19]
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481) ~[postgresql-42.2.19.jar:42.2.19]
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401) ~[postgresql-42.2.19.jar:42.2.19]
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164) ~[postgresql-42.2.19.jar:42.2.19]
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:130) ~[postgresql-42.2.19.jar:42.2.19]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-3.4.5.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.5.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3614) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3874) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:123) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:na]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:345) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562) ~[spring-orm-5.3.6.jar:5.3.6]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174) ~[spring-data-jpa-2.4.8.jar:2.4.8]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.6.jar:5.3.6]
at com.sun.proxy.$Proxy116.deleteById(Unknown Source) ~[na:na]
at com.rv02.evolvFit.Controller.deleteBlog(Controller.java:47) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.6.jar:5.3.6]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.6.jar:5.3.6]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.6.jar:5.3.6]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.6.jar:5.3.6]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.6.jar:5.3.6]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.6.jar:5.3.6]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.6.jar:5.3.6]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.6.jar:5.3.6]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.6.jar:5.3.6]
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:931) ~[spring-webmvc-5.3.6.jar:5.3.6]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.6.jar:5.3.6]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.45.jar:9.0.45]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.6.jar:5.3.6]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.6.jar:5.3.6]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93) ~[spring-boot-actuator-2.4.5.jar:2.4.5]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.6.jar:5.3.6]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
Relevant code blocks :
Blog.java
package com.rv02.evolvFit;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "Blogs")
public class Blog {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
private int id;
#Column
#NotBlank(message = "title is required")
private String title;
#Column
#NotBlank(message = "Post text is required")
private String text;
#OneToMany(mappedBy = "blog", cascade =
{CascadeType.PERSIST, CascadeType.REMOVE},
orphanRemoval = true, fetch = FetchType.LAZY)
private List<Comment> comments;
public Blog() {
this.comments = new ArrayList<>();
}
public Blog(int id, String title, String text, List<Comment> comments) {
this.id = id;
this.title = title;
this.text = text;
this.comments = comments;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
}
Comment.java
package com.rv02.evolvFit;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
#Entity
#Table(name = "Comments")
public class Comment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
private int id;
#Column
#NotBlank(message = "comment cannot be blank")
private String text;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "blog_id")
private Blog blog;
public Comment(int id, String text, Blog blog) {
this.id = id;
this.text = text;
this.blog = blog;
}
public Comment() {
}
public Comment(String text, Blog blog) {
this.text = text;
this.blog = blog;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Blog getBlog() {
return blog;
}
public void setBlog(Blog blog) {
this.blog = blog;
}
}
ParentChildComment.java
package com.rv02.evolvFit;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
#Entity
#Table(name = "Parent_Child_Comment")
public class ParentChildComment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonIgnore
private int id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "parent_comment_id", referencedColumnName = "id")
private Comment parentCommentID;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "child_comment_id", referencedColumnName = "id")
private Comment childCommentID;
public ParentChildComment(Comment parentCommentID, Comment childCommentID) {
this.parentCommentID = parentCommentID;
this.childCommentID = childCommentID;
}
public Comment getParentCommentID() {
return parentCommentID;
}
public void setParentCommentID(Comment parentCommentID) {
this.parentCommentID = parentCommentID;
}
public Comment getChildCommentID() {
return childCommentID;
}
public void setChildCommentID(Comment childCommentID) {
this.childCommentID = childCommentID;
}
}
Delete Blog Function
#DeleteMapping(path = "/blogs/{id}")
public Blog deleteBlog(#PathVariable int id) {
Blog blog = blogRepository.findById(id)
.orElseThrow(DataNotFoundException::new);
blogRepository.deleteById(id);
return blog;
}
Code blocks added/modified to make it work
Adding a custom function to ParentChildComment repository
#Query(
value = "select * from PARENT_CHILD_COMMENT where PARENT_COMMENT_ID in (select id from COMMENTS where BLOG_ID = ?1)",
nativeQuery = true
)
List<ParentChildComment> findBlogCommentRelationships(int id);
Modified deleteBlog()
#DeleteMapping(path = "/blogs/{id}")
public Blog deleteBlog(#PathVariable int id) {
Blog blog = blogRepository.findById(id)
.orElseThrow(DataNotFoundException::new);
parentChildCommentRepository.deleteAll(
parentChildCommentRepository.findBlogCommentRelationships(id)
);
blogRepository.deleteById(id);
return blog;
}
before invoking blogRepository.deleteById you should delete also ParentChildComment whose comments are in the Blog's collection of comments.

Trying and failing to create a DTO in Spring-boot DTO that grabs data from 3 tables

I'm coding an API that connects an online db to an android app and have gotten stuck on how to create a DTO that takes data from 3 tables that are connected with each other.
It's the first API I'm coding and I'm still trying to learn good practices so any suggestions are welcome.
I've reached the point where I really don't know where else to look for an answer, since all the answers I find are explaining how to use a query to take data from a single table(might be searching for it using the wrong terminology since I'm not a native English speaker)
These are the entities I create in the API:
Employees
#Entity
#Table(name = "employees")
public class Employees {
#Id
#Column(name = "eid")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int eid;
#Column(name = "first_name")
private String first_name;
#Column(name = "last_name")
private String last_name;
#Column(name = "birth_date")
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date birth_date;
#Column(name = "jid")
private int jid;
//Getters setters constructors
}
Jobs
#Entity
#Table(name = "jobs")
public class Jobs {
#Id
#Column(name = "jid")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int jid;
#Column(name = "job_name")
private String job_name;
//Getters setters constructors
}
Credentials
#Entity
#Table(name = "credentials")
#IdClass(CredentialsCID.class)
public class Credentials {
#Id
#Column(name = "username")
private String username;
#Id
#Column(name = "is_admin")
private byte is_admin;
#Column(name = "password")
private String password;
#Column(name = "eid")
private int eid;
//Getters setters constructors
}
And this is the dto class
EmployeesCustomDTO
package com.example.accessingdatamysql.dto;
import com.example.accessingdatamysql.model.Contracts;
import com.example.accessingdatamysql.model.Credentials;
import com.example.accessingdatamysql.model.Employees;
public class EmployeesCustomDTO {
private int eid;
private String first_name;
private String last_name;
private String jid;
private int hours;
private String type;
private byte is_admin;
public EmployeesCustomDTO() {
}
public EmployeesCustomDTO(int eid, String first_name, String last_name, String jid, int hours, String type, byte is_admin) {
this.eid = eid;
this.first_name = first_name;
this.last_name = last_name;
this.jid = jid;
this.hours = hours;
this.type = type;
this.is_admin = is_admin;
}
public int getEid() {
return eid;
}
public void setEid(int eid) {
this.eid = eid;
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public String getJob_name() {
return jid;
}
public void setJob_name(String job_name) {
this.jid = job_name;
}
public int getHours() {
return hours;
}
public void setHours(int hours) {
this.hours = hours;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public byte getIs_admin() {
return is_admin;
}
public void setIs_admin(byte is_admin) {
this.is_admin = is_admin;
}
public EmployeesCustomDTO convertToDTO(Employees employees, Credentials credentials, Contracts contracts){
EmployeesCustomDTO employeesCustomDTO = new EmployeesCustomDTO();
employeesCustomDTO.setEid(employees.getEid());
employeesCustomDTO.setFirst_name(employees.getFirst_name());
employeesCustomDTO.setLast_name(employees.getLast_name());
employeesCustomDTO.setJob_name(String.valueOf(employees.getJid())); // TODO: 19/12/2020 check if correct
employeesCustomDTO.setType(contracts.getType());
employeesCustomDTO.setHours(contracts.getHours());
employeesCustomDTO.setIs_admin(credentials.getIs_admin());
return employeesCustomDTO;
}
}
Then I added the following query to the EmployeesRepo (which works as I want it to when I try it on MySQL workbench)
#Repository
public interface EmployeesRepo extends JpaRepository<Employees, Integer> {
#Query(value = "SELECT employees.eid,employees.first_name,employees.last_name,employees.jid,contracts.hours,contracts.type,credentials.is_admin " +
"FROM employees,credentials,contracts " +
"WHERE employees.eid = credentials.eid AND contracts.eid = employees.eid", nativeQuery = true)
List<EmployeesCustomDTO> getCustomErgazomenoi();
}
and the following method in its service
#Override
public List<EmployeesCustomDTO> getCustomErgazomenoi() {
return employeesRepo.getCustomErgazomenoi();
}
which I then call in the controller
#GetMapping("/custom-employees")
public List<EmployeesCustomDTO> getAllCustomEmployees(){return employeesService.getCustomErgazomenoi();}
When I send the request to the endpoint I get the following error:
From Postman:
{
"timestamp": "2020-12-22T16:40:28.542+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/employees/custom-employees"
}
From the terminal in intellij
2020-12-22 18:40:28.527 ERROR 2948 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.core.co
nvert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.example.accessingdatamysql.dto.EmployeesCustomDTO]] with root cause
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.example.accessingdatamysql.dto.EmployeesCusto
mDTO]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322) ~[spring-core-5.3.1.jar:5.3.1]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) ~[spring-core-5.3.1.jar:5.3.1]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) ~[spring-core-5.3.1.jar:5.3.1]
at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:309) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:225) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:236) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:156) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:158) ~[spring-data-jpa-2.4.1.jar:2.4.1]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:143) ~[spring-data-jpa-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:131) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.4.1.jar:2.4.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:371) ~[spring-tx-5.3.1.jar:5.3.1]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:134) ~[spring-tx-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:145) ~[spring-data-jpa-2.4.1.jar:2.4.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.1.jar:5.3.1]
at com.sun.proxy.$Proxy120.getCustomErgazomenoi(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.1.jar:5.3.1]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.1.jar:5.3.1]
at com.sun.proxy.$Proxy77.getCustomErgazomenoi(Unknown Source) ~[na:na]
at com.example.accessingdatamysql.services.impl.EmployeesServiceImpl.getCustomErgazomenoi(EmployeesServiceImpl.java:45) ~[classes/:na]
at com.example.accessingdatamysql.controllers.EmployeesController.getAllCustomEmployees(EmployeesController.java:28) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.1.jar:5.3.1]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:893) ~[spring-webmvc-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:807) ~[spring-webmvc-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061) ~[spring-webmvc-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961) ~[spring-webmvc-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.1.jar:5.3.1]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.39.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.1.jar:5.3.1]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.39.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.39.jar:9.0.39]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.1.jar:5.3.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.1.jar:5.3.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.1.jar:5.3.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.1.jar:5.3.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.1.jar:5.3.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.1.jar:5.3.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
Even though I've found some answers on how to fix this problem I can't seem to get it to work on my API. Any suggestions?
Can you provide the code for EmployeesCustomDTO class? It looks like you are trying to perform a DTO projection which would require you to map the SQL result to the properties in the DTO.
If you are using hibernate you can create an appropriate constructor on the DTO and update query to use the new constructor:
#Query(value = "SELECT com.example.accessingdatamysql.dto.EmployeesCustomDTO(employees.eid,employees.first_name,employees.last_name,employees.jid,contracts.hours,contracts.type,credentials.is_admin) " +
"FROM employees,credentials,contracts " +
"WHERE employees.eid = credentials.eid AND contracts.eid = employees.eid")
List<EmployeesCustomDTO> getCustomErgazomenoi();
For a detailed explanation see - https://vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpa-and-hibernate/
Either way, you must provide the mapping from the SQL result set to your DTOs properties. If you are following standard naming conventions in SQL and Java the names are likely not identical - e.g. your query references first_name but I assume your DTO will be firstName.
Looks like you can also provide the mapping via #SqlResultSetMapping if you are using native queries: https://thorben-janssen.com/dto-projections/#DTO_projections_for_native_SQL_queries
Similar Stackoverflow post:
Spring JPA native query with Projection gives "ConverterNotFoundException"

Categories

Resources