0

I just try to create a CRUD Web Application with Spring Boot and I found that there is a problem with using Java Double Brace Initialization in the framework.

Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Unknown entity: com.example.service.impl.FileImageServiceImpl$1; nested exception is java.lang.IllegalArgumentException: Unknown entity:

I have the @Entity class:

@Entity
public class RandomEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
//Getter and Setter
}

A @RestController

@RestController
public class RandomController{

    @Autowired
    private RandomRepository  randomRepository;

    @GetMapping("/create")
    public String create(){
        RandomEntity rdEntity = new RandomEntity(){{
                setName("Bla Bla");
            }};
        return randomRepository.save();
    }
}

Here is the repository

   public interface RandomRepository extends CrudRepository<RandomEntity, Long> {
    }

But when I change Java Double Brace Initialization to Normal Initialization, the Application run properly.

Do you know why is that? Thank you so much!

TranNgocKhoa
  • 423
  • 1
  • 6
  • 20

2 Answers2

4

It may look like a nifty shortcut that just calls the constructor of your class followed by some initialization methods on the created instance, but what the so-called double-brace initialization really does is create a subclass of your Entity class. Hibernate will no longer know how to deal with that.

So try to avoid it. It has a lot of overhead and gotchas just to save you a few keystrokes.

Thilo
  • 257,207
  • 101
  • 511
  • 656
2

I just want to complete the answer of @Thilo, If you want a clean code use Builder design pattern, now you can implement this Design easily via Lombok library, so you can Just annotate your Entity like so :

@Entity
@Getter @Setter @NoArgsConstructor @AllArgsConstructor
@Builder(toBuilder = true)
class RandomEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

So there are really some cool annotations, for example @Getter and @Setter to avoid all that getters and setters, @Builder(toBuilder = true) to work with builder design so your controller can look like :

@GetMapping("/create")
public RandomEntity create() {

    // Create your Object via Builder design
    RandomEntity rdEntity = RandomEntity.builder()
            .name("Bla Bla")
            .build();

    // Note also here save should take your Object and return RandomEntity not a String
    return randomRepository.save(rdEntity);
}
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140