Как использовать @Autowired в классе, аннотированном @Entity? - PullRequest
1 голос
/ 02 октября 2019

У меня есть объект с именем TimeBooking . Когда я запрашиваю эту сущность и возвращаюсь к клиенту, я хочу получить список ActivityTimeBookings из репозитория. Но когда функция вызывается, репо становится пустым. Поэтому я попытался @Autowired репо и пометил его как временный, а также сказал Spring, что есть зависимость, которая должна быть введена.

@Configurable(preConstruction = true)
@Entity
public class TimeBooking extends BaseEntity{

    @Autowired
    private transient ActivityTimeBookingRepository activityTimeBookingRepository;

    ...

    @JsonProperty("activityTimeBookings")
    private List<ActivityTimeBooking> activityTimeBookings() {
        return this.activityTimeBookingRepository.findByDate(this.timeFrom);
    }
}

Есть предложения?

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Использование @Autowired в классе, помеченном @Entity, неверно.

Решение приведено ниже:

1. Создайте интерфейс службы:

public interface TimeBookingService {

   public List<ActivityTimeBooking> activityTimeBookings();

}  

2. Создайте реализацию интерфейса службы:

@Service
public class TimeBookingServiceImpl implements TimeBookingService {

    @Autowired
    private ActivityTimeBookingRepository activityTimeBookingRepository;

    public List<ActivityTimeBooking> activityTimeBookings() {
        return this.activityTimeBookingRepository.findByDate(this.timeFrom);
    }
}
0 голосов
/ 02 октября 2019

Обычно это действительно плохая практика - вводить что-либо в объекты JPA. Обычно они создаются реализацией JPA (например, Hibernate) и Spring, поскольку DI-фреймворк на самом деле не участвует в этом процессе.

Обратите внимание, что может быть много экземпляров этого класса, созданных в результате запроса,поэтому, если вы позже будете использовать это для сериализации списка этого объекта, вы можете в конечном итоге выполнить N запросов к базе данных, учитывая, что было получено N подобных объектов.

Отвечая на ваш вопрос о «получении доступа к репо», яПолагаю, вам следует подумать о рефакторинге:

В классе обслуживания (при условии, что у вас есть «обычный» контроллер, сервис и дао):

вы можете:

class MyService {
    SomeResult.. doSomething() {
     List<TimeBooking> allTimeBookings = dao.getAllTimeBooking();
     LocalDateTime timeFrom = calculateTimeFrom(allTimeBookings);
     List<ActivityTimeBooking> allActivityTimeBookings = dao.findByDate(timeFrom);
     return calculateResults(allTimeBookings, allActivityTimeBooking);        
    }
}

class MyDao {
  List<ActivityTimeBooking> findByDate(LocalDateTime timeFrom) {...}

  List<TimeBooking> getAllTimeBookings() {...}
}

Относительнореализация сервиса, я предположил, что этот вариант использования не может быть покрыт обычным «СОЕДИНЕНИЕМ между двумя таблицами», так что создание связи между TimeBooking и ActivityTimeBooking не вариант.

Примечание2, я использовал один репозиторий (дао) для краткости, в реальном приложении вы можете внедрить в сервис два разных репозитория.

...