2015-11-03 2 views
2

Я использую репозитории и сущности Spring JPA в приложении. Теперь, в духе этого приложения, мне нужно расширить один из моих объектов, а также предоставить расширенный репозиторий.@ Приоритетный эквивалент для автономных репозиториев Spring JPA

Для всех остальных компонентов мне нужно переопределить/расширить. Я просто создаю новую реализацию и комментирую ее с помощью @Primary, поэтому она будет автоматически открыта вместо стандартной реализации.

Для репозиториев, однако, это не работает. Я могу аннотировать новый репозиторий с помощью @Primary, но он не имеет никакого эффекта (оба компонента найдены и поэтому не могут быть автообновлены). Это имеет смысл, потому что репозиторий является интерфейсом, а не реализацией, реализация осуществляется Spring динамически.

Могу ли я как-то рассказать Spring (через аннотацию в репозитории или через конфигурацию), какой репозиторий использовать? Или мне нужно сделать ручное обходное решение, подобное этому Using @Primary in Spring Data JPA repositories, или я должен придумать своего рода поставщик репозитория вместо autowiring?

Редактировать, чтобы сделать вещи яснее: Скажем, у меня есть сущность A

@Entity 
public class A { 
    @Id 
    private long id; 
} 

и его хранилище

public ARepository extends Repository<A, Long> { 
} 

Теперь я продлить его сущности B

@Entity 
public class B extends A { 
} 

public interface BRepository extends ARepository { 
} 

Обычно, согласно документации, вы используете хранилища, как это:

@Autowired 
private ARepository repository; 

Это, однако, не работает, потому что теперь есть два фасоль типа ARepository. Для бобров, которые я реализую сам, я бы использовал @Primary в расширяющемся классе, но для репозиториев нет реализации интерфейса во время компиляции.

+0

Почему расширение сущностей и репозитория для этого объекта требует того, что вы описываете во втором абзаце. ... Может быть, абзац 2. должен быть перефразирован - я (и он никого не швыряет) понимает, что вы хотите сделать/что ваша проблема. – Ralph

+0

@Ralph Я добавил несколько примеров кода, чтобы объяснить, что моя проблема.Существует также связанный вопрос, когда я пытаюсь использовать фабрику хранилища вместо обычной автоустановки. –

+0

Теперь я понял. - интересный вопрос. – Ralph

ответ

3

Я бы адаптировать идею сформировать этот ответ: https://stackoverflow.com/a/27549198/280244 и этот GIT пример https://github.com/netgloo/spring-boot-samples/tree/master/spring-boot-springdatajpa-inheritance/src/main/java/netgloo/models

ввести общую абстрактную Repository, помеченный с @NoRepositoryBean

@NoRepositoryBean 
public interface AbstractARepository<T extends A> 
            extends Repository<T, Long> { 
    T findByName(String name); //or what ever your queries are 
} 

public ARepository extends AbstractARepository<A> { 
    //almost emtpy 
} 


public BRepository extends AbstractARepository<B> { 
    //queries that are special for B 
} 

Теперь вы можете вводить ARepository и BRepository, и как есть тип save!

+0

Конечно, я прочитал вопрос, который вы связали раньше, но я подумал, что это не применимо к моему делу. Ваш пример кода очень интересен. Это хорошее решение, если вы хотите использовать 'A' вместе с' B'. В моем случае, однако, я хочу «переопределить» объект таким образом, что '@Autowire ARepository' фактически возвращает реализацию' BRepository', так что enitities создаются как 'B' и не нужно загружать снова, если я хотите использовать функциональность 'B'. Это будет поведение традиционных фасов '@ Primary'. –

+0

@zero_cool: внимательно ознакомьтесь с моим предложением. Дело в том, что 'ARepository' и' BRepository' пусты. Вы можете ввести тип «ARepository» или «BRepository» по типу. Конечно, «BRepository» не расширяет «ARepository», но я не ожидаю, что это необходимо. – Ralph

+0

@zero_cool: Но я никогда не буду загружать объекты 'B' снова, тогда нет причин вообще иметь« BRepository ». - Или зачем вам это нужно? – Ralph

1

Просто для записи, можно добавить поддержку @Primary в JPA хранилищами, как предложено здесь Using @Primary in Spring Data JPA repositories

Моя реализация недостающего кода:

private boolean isSpringDataJpaRepository(Class<?> beanClass) { 
     return JpaRepositoryFactoryBean.class.isAssignableFrom(beanClass); 
} 

Я думаю, что ответ @Ralph лучше из-за безопасности типа.

Смежные вопросы