I am a beginner in spring and trying to use Spring Data JDBC to persist data. I have made the necessary changes to the Repository interfaces by extending them with Repository/CrudRepositoy. Also, for preloading data into the h2 database, I have also set up a data_Loader_Config class with an ApplicationRunner. Still, Spring data cannot set the id property to one of the fields in the Ingredient class. I don't know what to do here...
PS - After creating an applicationRunner instance should I delete the data.sql file that I was using earlier to preload data.
package tacos;
import lombok.Data;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Persistable;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import java.beans.ConstructorProperties;
@Data
@Table
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
public class Ingredient implements Persistable<String> {
@Id
private final String id;
private final String name;
private final Type type;
public enum Type {
WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
}
// @ConstructorProperties({"id", "name", "type"})
// public Ingredient(String id, String name, Type type) {
// this.id = id;
// this.name = name;
// this.type = type;
// }
@Override
public boolean isNew() {
// You can implement your logic here to determine if the ingredient is new or not.
// For example, you can check if the 'id' property is null.
return id == null;
}
}
package tacos;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.ApplicationRunner;
import tacos.data.IngredientRepository;
public class DataLoaderConfig {
@Bean
public ApplicationRunner dataLoader(IngredientRepository repo) {
return args -> {
repo.save(new Ingredient("FLTO", "Flour Tortilla", Ingredient.Type.WRAP));
repo.save(new Ingredient("COTO", "Corn Tortilla", Ingredient.Type.WRAP));
repo.save(new Ingredient("GRBF", "Ground Beef", Ingredient.Type.PROTEIN));
repo.save(new Ingredient("CARN", "Carnitas", Ingredient.Type.PROTEIN));
repo.save(new Ingredient("TMTO", "Diced Tomatoes", Ingredient.Type.VEGGIES));
repo.save(new Ingredient("LETC", "Lettuce", Ingredient.Type.VEGGIES));
repo.save(new Ingredient("CHED", "Cheddar", Ingredient.Type.CHEESE));
repo.save(new Ingredient("JACK", "Monterrey Jack", Ingredient.Type.CHEESE));
repo.save(new Ingredient("SLSA", "Salsa", Ingredient.Type.SAUCE));
repo.save(new Ingredient("SRCR", "Sour Cream", Ingredient.Type.SAUCE));
};
}
}
package tacos.data;
import org.springframework.data.repository.CrudRepository;
import tacos.Ingredient;
public interface IngredientRepository extends CrudRepository<Ingredient, String> {
}
2023-08-27T13:33:12.697+05:30 ERROR 13080 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.servi
ce() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.Illeg
alStateException: Cannot set property id because no setter, no wither and it's not part of the persistence constructor p
rivate tacos.Ingredient()] with root cause
java.lang.IllegalStateException: Cannot set property id because no setter, no wither and it's not part of the persistenc
e constructor private tacos.Ingredient()
at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePrope
rtyAccessor.java:94) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setProperty(SimplePersistentPrope
rtyPathAccessor.java:108) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.mapping.model.ConvertingPropertyAccessor.setProperty(ConvertingPropertyAccessor.java
:60) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.lambda$populateProperties$0(Basi
cJdbcConverter.java:433) ~[spring-data-jdbc-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:298)
~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.mapping.PersistentEntity.doWithAll(PersistentEntity.java:297) ~[spring-data-commons-
3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.populateProperties(BasicJdbcConv
erter.java:418) ~[spring-data-jdbc-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.createInstanceInternal(BasicJdbc
Converter.java:562) ~[spring-data-jdbc-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.mapRow(BasicJdbcConverter.java:4
10) ~[spring-data-jdbc-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter.mapRow(BasicJdbcConverter.java:305) ~[spring-da
ta-jdbc-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.jdbc.core.convert.EntityRowMapper.mapRow(EntityRowMapper.java:79) ~[spring-data-jdbc
-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:94) ~[
spring-jdbc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:61) ~[
spring-jdbc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:729) ~[spring-jdbc-6.1.0
-M4.jar:6.1.0-M4]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:654) ~[spring-jdbc-6.1.0-M4.jar:6.1.0-M4
]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:719) ~[spring-jdbc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:744) ~[spring-jdbc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:800) ~[spring-jdbc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:218
) ~[spring-jdbc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:230
) ~[spring-jdbc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.data.jdbc.core.convert.DefaultDataAccessStrategy.findAll(DefaultDataAccessStrategy.java:2
74) ~[spring-data-jdbc-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.jdbc.core.JdbcAggregateTemplate.findAll(JdbcAggregateTemplate.java:341) ~[spring-dat
a-jdbc-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.jdbc.repository.support.SimpleJdbcRepository.findAll(SimpleJdbcRepository.java:89) ~
[spring-data-jdbc-3.2.0-M2.jar:3.2.0-M2]
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.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lamb
da$new$0(RepositoryMethodInvoker.java:288) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.jav
a:136) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:
120) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryC
omposition.java:516) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterc
eptor.invoke(RepositoryFactorySupport.java:628) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[s
pring-aop-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodI
nterceptor.java:168) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInt
erceptor.java:143) ~[spring-data-commons-3.2.0-M2.jar:3.2.0-M2]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[s
pring-aop-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterce
ptor.java:123) ~[spring-tx-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspec
tSupport.java:392) ~[spring-tx-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[
spring-tx-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[s
pring-aop-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTransla
tionInterceptor.java:137) ~[spring-tx-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[s
pring-aop-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~
[spring-aop-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[s
pring-aop-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244) ~[spring-aop-6.1.0-M
4.jar:6.1.0-M4]
at jdk.proxy4/jdk.proxy4.$Proxy93.findAll(Unknown Source) ~[na:na]
at tacos.web.DesignTacoController.addIngredientsToModel(DesignTacoController.java:42) ~[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:253) ~[spr
ing-web-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:18
1) ~[spring-web-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.method.annotation.ModelFactory.invokeModelAttributeMethods(ModelFactory.java:143) ~[s
pring-web-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.method.annotation.ModelFactory.initModel(ModelFactory.java:112) ~[spring-web-6.1.0-M4
.jar:6.1.0-M4]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(Reques
tMappingHandlerAdapter.java:895) ~[spring-webmvc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMapp
ingHandlerAdapter.java:830) ~[spring-webmvc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.j
ava:87) ~[spring-webmvc-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1086) ~[spring-webmvc-6.1
.0-M4.jar:6.1.0-M4]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.0
-M4.jar:6.1.0-M4]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6
.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.1.0-M4.ja
r:6.1.0-M4]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.12.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.0-M4.
jar:6.1.0-M4]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.12.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-em
bed-core-10.1.12.jar:10.1.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core
-10.1.12.jar:10.1.12]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.12.jar:1
0.1.12]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-em
bed-core-10.1.12.jar:10.1.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core
-10.1.12.jar:10.1.12]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-
web-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.
0-M4.jar:6.1.0-M4]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-em
bed-core-10.1.12.jar:10.1.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core
-10.1.12.jar:10.1.12]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1
.0-M4.jar:6.1.0-M4]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.
0-M4.jar:6.1.0-M4]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-em
bed-core-10.1.12.jar:10.1.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core
-10.1.12.jar:10.1.12]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[s
pring-web-6.1.0-M4.jar:6.1.0-M4]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.
0-M4.jar:6.1.0-M4]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-em
bed-core-10.1.12.jar:10.1.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core
-10.1.12.jar:10.1.12]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.
12.jar:10.1.12]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.1
2.jar:10.1.12]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10
.1.12.jar:10.1.12]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.12.jar
:10.1.12]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.12.jar:
10.1.12]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.12.
jar:10.1.12]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.12.jar:1
0.1.12]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.12.jar:10
.1.12]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.12.
jar:10.1.12]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-1
0.1.12.jar:10.1.12]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740) ~[tomcat-embed-core-10.1.
12.jar:10.1.12]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.12.j
ar:10.1.12]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core
-10.1.12.jar:10.1.12]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core
-10.1.12.jar:10.1.12]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.1
2.jar:10.1.12]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
I think the error message speaks for itself:
Cannot set property id because no setter, no wither and it's not part of the persistenc e constructor
Spring Data JDBC sets the id of an entity after saving it. For this it needs a way to set it. There are many variants how to achieve this:
final
and not private
.final
and provide a setter.withId
method, taking the new id and returning a new entity instance with the new id applied.@PersistenceInstantiator
), that takes the id as an argument.And yes, if you don't use data.sql
anymore, because you initialise the data in the application, you may and actually should delete it.