0

Having these entity:

@Entity
@Data
@Builder
public class User {
    @Id
    private int id;
    private String name;
}

If i try to set the id:

@Bean
    CommandLineRunner dataLoader(UserRepository userRepo){
        return new CommandLineRunner() {
            @Override
            public void run(String... args) throws Exception {
                User u = User.builder()
                        .id(1)
                        .name("First User")
                        .build();
                userRepo.save(u);
            }
        };
    }

I got

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:794) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:775) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:345) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.3.jar:2.5.3]
    at com.example.demo.DemoApplication.main(DemoApplication.java:16) ~[classes/:na]
Caused by: org.springframework.orm.jpa.JpaSystemException: No default constructor for entity:  : com.example.demo.domain.User; nested exception is org.hibernate.InstantiationException: No default constructor for entity:  : com.example.demo.domain.User
...

If i don't set the id, then no problem. So how do I can set the primary manually?

1

1 Answer 1

2

In General: You sholdn't use @Data with Entities because the generated equals/hashCode and toString can lead to StackOverflowError if you have bi-directional entities.

Coming back to your question JPA needs a default constructor (no args constructor)

So I would recommend this:

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    @Id
    private int id;
    private String name;
}
Sign up to request clarification or add additional context in comments.

10 Comments

1) I don't understand your point of StackoverfloError, could you give an example please? 2) Why does not @Builder provide default (no-arg) constructor? Why does this behvaiour the @Builder overwrites? 3) Why does this issue (regarding the lack of default constructor) solves by adding @AllArgsConstrutor, which is not default constructor?
1) equals/hashCode/toString will follow the references and will produce an endless loop 2 and 3) Please read the API Doc projectlombok.org/api/lombok/Builder.html
So when it is safe to use @Data, when in case of @Entity, it would create infinite loop? When it doesn't ?
Btw, your annotations are not enough. It will fail anyway, unless @AllArgsConstrutor is provided. The error otherwise: constructor User in class com.example.demo.model.User cannot be applied to given types; required: no arguments found: int,java.lang.String reason: actual and formal argument lists differ in length
Ah you're right the Builder requires the AllArgsConstructor.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.