0

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;
}
juuubbb
  • 139
  • 4
  • 14

1 Answers1

1

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

  • Still got the same NullPointer Exc. on the autowired crudrepo. But Im a little confused about the comments in the posted link.. They annotated sthing like that: @Bean public AutowireHelper autowireHelper(){ return AutowireHelper.getInstance(); } – juuubbb May 20 '19 at 19:56
  • Would you try now? Changed some things, lets see will that work – Milenko Jevremovic May 20 '19 at 20:27
  • try with one repository, exclude second for a sec – Milenko Jevremovic May 20 '19 at 20:42
  • tried still not working.. the listener is called cause of the DatabaseInitializer, which is called on startup. Maybe this has something to do with the problem? – juuubbb May 20 '19 at 20:48
  • probably, depends how you resolve that, when is initialized – Milenko Jevremovic May 20 '19 at 20:51
  • any other suggestion for implementing database trigger in java since writing triggers in schema.sql and generating database from spring.jpa.hibernate.ddl-auto does not work together? – juuubbb May 20 '19 at 21:08