Nuñito Calzada
Nuñito Calzada

Reputation: 2096

@EntityListeners in SpringBoot

I have created this EntityListener:

@Slf4j
@Component
public class AListener {

    private final ARepository aRepository;

    public AListener(ARepository aRepository) {
        this.aRepository = aRepository;
    }


    ...
}

that I use here:

@Entity
@EntityListeners(AListener.class)
@Table(name = "CAT")
@NoArgsConstructor
@AllArgsConstructor
public class Cat implements Serializable {
..
}

but I see this error: Class 'AListener' should have [public] no-arg constructor

and in the logs:

Exception Description: Error encountered when instantiating the class [class com.poli.listener.AListener].
Internal Exception: java.lang.InstantiationException: com.poli.listener.AListener]

Upvotes: 6

Views: 6605

Answers (1)

Semyon Kirekov
Semyon Kirekov

Reputation: 1442

EntityListener is JPA feature, not Spring ones. You don't need to declare a listener as a @Component, because the JPA provider shall instantiate it.

That's what actually happens here:

  1. Spring instantiates a AListener bean and injects ARepository dependency as expected.
  2. JPA provider sees that AListener is an entity listener and tries to instantiate it. In order to do it needs no-args constructor (remember that JPA provider knows nothing about Spring and its beans)
  3. Instantiation fails, because no-args constructor is not found

You can check it by removing the ARepository dependency and adding some logging statements inside the constructor.

If you do need some Spring beans inside the listener you can make them accessible as static fields in some utility class.

Upvotes: 5

Related Questions