0

I want to do a GET Request with postman, but I get the following response

{
"cause": null,
"message": "Id must be assignable to Serializable!: null"
}

For example when I call this endpoint http://localhost:8080/expenses/search/findAllByOrderByDateDesc

I get the error from above.

My Expense model looks like this

@Entity
@DiscriminatorValue("Expenses")
public class Expense extends FinancialRecord {

    @NotNull
    @Size(min = 1, message="Empfänger muss mindestens 1 Zeichen lang sein.")
    private String recipient;

    public Expense() {
    }

    public Expense(
            Date date,
            BigDecimal amount,
            String recipient,
            String item,
            Category category,
            PaymentMethod paymentMethod
    ) {
        super(date, amount, item, category, paymentMethod);
        this.recipient = recipient;
    }

It extends this super class here:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discriminator")
@EntityListeners(AuditingEntityListener.class)
public abstract class FinancialRecord extends DateEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Temporal(TemporalType.DATE)
    @NotNull(message="Datum muss angegeben werden.")
    private Date date;

    @NotNull(message="Betrag muss angegeben werden.")
    @DecimalMin(value="0.01", message="Betrag muss mindestens 0.01 sein.")
    private BigDecimal amount;

    @NotNull(message="Gegenstand muss angegeben werden.")
    @Size(min=1, message="Gegenstand muss mindestens 1 Zeichen lang sein.")
    private String item;

    @ManyToOne(optional = false)
    private Category category;

    @Enumerated(EnumType.STRING)
    @NotNull(message="Zahlungsart muss angegeben werden.")
    private PaymentMethod paymentMethod;

    public FinancialRecord(
            Date date,
            BigDecimal amount,
            String item,
            Category category,
            PaymentMethod paymentMethod
    ) {
        this.date = date;
        this.amount = amount;
        this.item = item;
        this.category = category;
        this.paymentMethod = paymentMethod;
    }

    public FinancialRecord() {}

I have an ID with the annotation @ID and all the data could be saved in the DB (already checked in pgAdmin 4)

My ExpenseRepository looks like this

@RepositoryRestResource
public interface ExpensesRepository extends CrudRepository<Expense, Long> {
    List<Expense> findByItem(String item);
    List<Expense> findAllByOrderByDateDesc();
    Iterable<Expense> findAll(Pageable page);
}

I want to call the findAllByOrderByDateDesc() via GET Request, but get the error from above.

But calling in the CommandLineRunner like this

exRepo.findAllByOrderByDateDesc().forEach(e -> {
                log.info(e.toString());
            });

works...

So I am not sure what kind of error this is?

EDIT:

Here is the stack trace

java.lang.IllegalArgumentException: Id must be assignable to Serializable!: null
    at org.springframework.util.Assert.instanceCheckFailed(Assert.java:702) ~[spring-core-5.3.5.jar:5.3.5]
    at org.springframework.util.Assert.isInstanceOf(Assert.java:602) ~[spring-core-5.3.5.jar:5.3.5]
    at org.springframework.data.rest.webmvc.support.RepositoryEntityLinks.linkToItemResource(RepositoryEntityLinks.java:156) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at org.springframework.data.rest.core.support.DefaultSelfLinkProvider.createSelfLinkFor(DefaultSelfLinkProvider.java:68) ~[spring-data-rest-core-3.4.6.jar:3.4.6]
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.getExpandedSelfLink(PersistentEntityResourceAssembler.java:116) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.wrap(PersistentEntityResourceAssembler.java:94) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.toModel(PersistentEntityResourceAssembler.java:73) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.entitiesToResources(AbstractRepositoryRestController.java:110) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.toCollectionModel(AbstractRepositoryRestController.java:80) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at org.springframework.data.rest.webmvc.RepositorySearchController.lambda$toModel$1(RepositorySearchController.java:204) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at java.base/java.util.Optional.map(Optional.java:260) ~[na:na]
    at org.springframework.data.rest.webmvc.RepositorySearchController.toModel(RepositorySearchController.java:201) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at org.springframework.data.rest.webmvc.RepositorySearchController.executeSearch(RepositorySearchController.java:185) ~[spring-data-rest-webmvc-3.4.6.jar:3.4.6]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[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:567) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.44.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.5.jar:5.3.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.44.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
    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.44.jar:9.0.44]
    at java.base/java.lang.Thread.run(Thread.java:831) ~[na:na]

2021-05-11 12:38:43.142  WARN 37200 --- [nio-8082-exec-2] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [java.lang.IllegalArgumentException: Id must be assignable to Serializable!: null]

Process finished with exit code -1
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Haidepzai
  • 764
  • 1
  • 9
  • 22
  • `"message": "Id must be assignable to Serializable!: null"` This looks like a customized error message. Can you update the question with the stack trace? – justthink May 11 '21 at 10:58
  • Okay, I updated it – Haidepzai May 11 '21 at 11:06
  • Does this answer your question? [How to annotate MYSQL autoincrement field with JPA annotations](https://stackoverflow.com/questions/4102449/how-to-annotate-mysql-autoincrement-field-with-jpa-annotations) – Kaustubh Khare May 11 '21 at 11:15
  • In some case one of your Entity ID is null. You can check it in debug mode. Here some links to source code [link1](https://github.com/spring-projects/spring-data-rest/blob/main/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java#L156) [link2](https://github.com/spring-projects/spring-framework/blob/4f2c589fe649cc09cf3d03b440b3b0a2899a1d1c/spring-core/src/main/java/org/springframework/util/Assert.java#L687) – Grigorii Riabov May 11 '21 at 11:36

2 Answers2

0

Expense modal does not have a field annotated with @Id

@Entity
@DiscriminatorValue("Expenses")
public class Expense extends FinancialRecord {

    @NotNull
    @Size(min = 1, message="Empfänger muss mindestens 1 Zeichen lang sein.")
    private String recipient;
// ...

You might think that Expense extends FinancialRecord, which does have id annotated with @Id. For entities, hibernate does not map the child class to the parent class (super class) by default.

You can add @javax.persistence.MappedSuperclass to the parent class (super class). In your case, it would be:

@MappedSuperclass // **Add this annotation to the parent class**
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discriminator")
@EntityListeners(AuditingEntityListener.class)
public abstract class FinancialRecord extends DateEntity {
// ...

@Haidepzai You are right. You can annotate a class with either @MappedSuperclass or @Entity. I assume that FinancialRecord class does not correspond to a table in database, and you only use FinancialRecord abstract class to retain common fields for multiple entity classes (tables).

In this case, you just need to remove @Entity and add @MappedSuperclass for abstract class FinancialRecord.

justthink
  • 439
  • 3
  • 6
  • 1
    Thanks. But I think `@MappedSuperclass` collides with `@Entity`? I got this error then `Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: An entity cannot be annotated with both @Entity and @MappedSuperclass:` – Haidepzai May 11 '21 at 11:24
  • `http://localhost:8080/financialRecords/search/findAllByOrderByDateDesc` seems also not to work even though the ID is set for `FinancialRecords` but get the same error – Haidepzai May 11 '21 at 11:41
  • You are right. `@Entity` should not co-exist with `@MappedSuperclass`. I updated answer. Please let me know if it fixes the problem this time. @Haidepzai – justthink May 11 '21 at 11:55
0

Use long instead of Long as id type in FinancialRecord:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
funkyfox
  • 23
  • 4