-2

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.

Here is my Ingredient class:

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;
    }


}

This is my Data_Loader_config class:

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));
        };
    }
}

This is the ingredient repository which extends Repsitory/CrudRepsitory Interface:

package tacos.data;

import org.springframework.data.repository.CrudRepository;
import tacos.Ingredient;

public interface IngredientRepository extends CrudRepository<Ingredient, String> {
   
}

Finally this is the stac trace:

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]
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348

1 Answers1

1

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:

  • make it not final and not private.
  • make it not final and provide a setter.
  • provide a wither, i.e. a withId method, taking the new id and returning a new entity instance with the new id applied.
  • provide a constructor (if it isn't the only constructor, mark it as @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.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • Hey, thanks for your comment. So just to clarify, If I go with the first variant option as mentioned by you, I should just remove both "private" and "final" keywords from the properties of the Ingredient class. Is that right or am I missing something? – Raghav Kavimandan Aug 27 '23 at 13:34
  • That should be sufficient. – Jens Schauder Aug 27 '23 at 17:07