@ Первичный на лету - PullRequest
0 голосов
/ 21 мая 2018

Мне нужен совет.

У меня есть базовый проект Maven, в котором я объявляю все свои репозитории, сущности и классы постоянства.Все они настроены без XML.Каждая база данных и все связанные с ней классы разделены на пакеты.Все аннотировано в этом проекте, например: @Entity, @Repository, @Configuration, @Primary и т. Д. ... Это выглядит так:

enter image description here

Сейчас бины в пакете radiusfttx.domain аннотируются как @Primary.Этот проект по сути своей, он ничего не делает сам по себе.

Затем, когда я создаю новый проект, которому требуется доступ к любой из баз данных, я просто импортирую первый проект с Maven и, в новом проектеинициализации, я изменяю это так (это Kotlin, но я уверен, что вы можете понять идею):

@SpringBootApplication
@ComponentScan(basePackages = [
    "com.entre.rest.boot", <-- my main class is here
    "com.entre.databases.mailserver.domain", <-- repos from the other project
    "com.entre.databases.integrator.domain" ])

Поскольку все уже аннотировано, автоконфигурация Spring-boot выбирает классы и создает компонентыбез проблем.Ну, по крайней мере, до тех пор, пока я не попытаюсь зафиксировать что-либо в базе данных.

Поскольку только одно постоянство может иметь аннотацию @Primary, если я не добавлю это постоянство в @ComponentScan, все просто не будет работать.Как вы можете видеть в приведенном выше примере, я не добавил «radiusfttx.domain» в @ComponentScan, и @Primary там.

Поэтому мой вопрос: есть ли способ, которым я могу установить @Primaryна лету?Быть аннотированным и жестко закодированным не работает для того, что я пытаюсь сделать здесь.Есть идеи?

Заранее спасибо.

РЕДАКТИРОВАТЬ 1

В качестве обходного пути я создал "фиктивную" стойкость H2, которую я помечаю как @Primaryи добавить ко всем моим проектам.Таким образом, все мои «настоящие» источники данных не нужно устанавливать @Primary.Это далеко от решения этого случая, но это работает.Вопрос остается открытым, если кто-то может придумать что-нибудь получше.

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "emfDummy", transactionManagerRef = "tmDummy",
        basePackages = ["com.entre.databases.dummy.domain"])
class DummyPersistence {
    @Primary
    @Bean("dsDummy")
    fun dataSource() = HikariDataSource().apply {
        username = "sa"
        password = "sa"
        jdbcUrl = "jdbc:h2:mem:db;DB_CLOSE_DELAY=-1"
        driverClassName = "org.h2.Driver"
    }

    fun hibernateJpaVendorAdapter() = HibernateJpaVendorAdapter().apply {
        setDatabasePlatform("org.hibernate.dialect.H2Dialect")
        setShowSql(false)
        setGenerateDdl(true)
    }

    @Primary
    @Bean("emfDummy")
    fun entityManagerFactory() = LocalContainerEntityManagerFactoryBean().apply {
        setPackagesToScan("com.entre.databases.dummy.domain")
        jpaVendorAdapter = hibernateJpaVendorAdapter()
        dataSource = dataSource()
        persistenceUnitName = "puDummy"
        afterPropertiesSet()
    }

    @Primary
    @Bean("tmDummy")
    fun transactionManager() = JpaTransactionManager().apply {
        entityManagerFactory = entityManagerFactory().`object`
    }
}

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Спасибо за все ответы, вы заставили меня посмотреть в правильном направлении.

Хотя я понимаю использование @Qualifier, этого было недостаточно для моего конкретного проекта, потому что, насколько я мог понять,аннотация должна быть в импортируемом проекте «библиотека».Моя проблема действительно связана с транзакцией, поскольку я не могу указать @Primary после импорта определенного пакета, в котором постоянная конфигурация еще не помечена как @ Primary.

Итак, вот как я решил ее.

Вместо того, чтобы просто создавать репозитории в проекте "библиотека", я также создал там слой @Service.Эти @Services я также могу аннотировать с помощью @Transactional и назвать транзакцию, которую SpringManager должен использовать для этой конкретной службы.Так, например, в «ServiceDummy» я могу добавить @Transactional («tmDummy») и автоматически связать только @Service с другим приложением.Таким образом, Spring не спорит о том, чтобы на выбор было 2, 3 или более.

@SpringBootApplication
@ComponentScan(basePackages = [
    "com.entre.rest.boot",
    "com.entre.databases.dummy.service",
    "com.entre.rest.web"
])
class Application

fun main(args: Array<String>) {
    runApplication<Application>(*args)
}
0 голосов
/ 22 мая 2018

Вы можете либо использовать @Qualifier, либо вообще не помечать свой компонент как @Component, вместо этого оставьте их как простые классы в своей библиотеке и установите в качестве клиентского приложения в качестве @Bean.1004 *

Таким образом, вы можете либо иметь один источник данных, либо, если вам нужно больше, вы сможете добавить @Primary к @Bean, который вы хотите.

Что касается профилей, вы можете установитьдополнительные профили помимо prod / dev / test, например prod,ds1 prod,ds2 test,tds1 и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...