Reputation: 179
I have a class DatabaseInitializer which inserts some data via crudrepositories into my database. Now I added an EntityListener which should update a number in another table (table 2), if the date of the entity is not present in table 2. For this I try @Autowired with the crudrepository for this entity. But the repository isn't autowired correctly, it's always null.
The EntityListener:
@Component
public class OrderDayIdListener {
@Autowired
private static OrderRepository orderRepository;
@Autowired
private OrderDayIdRepository orderDayIdRepository;
@PrePersist
private void incrementOrderIdInTable(Order order) {
LocalDate date = order.getDate();
OrderDayId orderDayIdObject = orderDayIdRepository.findByDate(date);
if(orderDayIdObject == null){
orderDayIdObject = new OrderDayId(1L, date);
} else {
orderDayIdObject.incrementId();
}
Long orderDayId = orderDayIdObject.getId();
order.setOrderDayId(orderDayId);
orderDayIdRepository.save(orderDayIdObject);
orderRepository.save(order);
}
}
The Entity:
@EntityListeners(OrderDayIdListener.class)
@Data
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@Column(name ="date")
private LocalDate date;
}
Upvotes: 1
Views: 3128
Reputation: 1056
As I know you cannot inject spring managed beans into a JPA EntityListener. What I have found is to create helper class for do the job:
public final class AutowireHelper implements ApplicationContextAware {
private static final AutowireHelper INSTANCE = new AutowireHelper();
private static ApplicationContext applicationContext;
private AutowireHelper() {
}
/**
* Tries to autowire the specified instance of the class if one of the specified beans which need to be autowired
* are null.
*
* @param classToAutowire the instance of the class which holds @Autowire annotations
* @param beansToAutowireInClass the beans which have the @Autowire annotation in the specified {#classToAutowire}
*/
public static void autowire(Object classToAutowire, Object... beansToAutowireInClass) {
for (Object bean : beansToAutowireInClass) {
if (bean == null) {
applicationContext.getAutowireCapableBeanFactory().autowireBean(classToAutowire);
return;
}
}
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) {
AutowireHelper.applicationContext = applicationContext;
}
/**
* @return the singleton instance.
*/
public static AutowireHelper getInstance() {
return INSTANCE;
}}
than just do:
public class OrderDayIdListener {
@Autowired
private OrderRepository orderRepository;
@Autowired
private OrderDayIdRepository orderDayIdRepository;
@PrePersist
public void incrementOrderIdInTable(Order order) {
AutowireHelper.autowire(this, this.orderRepository);
AutowireHelper.autowire(this, this.orderDayIdRepository);
LocalDate date = order.getDate();
OrderDayId orderDayIdObject = orderDayIdRepository.findByDate(date);
if(orderDayIdObject == null){
orderDayIdObject = new OrderDayId(1L, date);
} else {
orderDayIdObject.incrementId();
}
Long orderDayId = orderDayIdObject.getId();
order.setOrderDayId(orderDayId);
orderDayIdRepository.save(orderDayIdObject);
orderRepository.save(order);
}}
full explanation here
Upvotes: 1