hibernate читать имя таблицы различных отношений после изменения нескольких источников данных - PullRequest
0 голосов
/ 05 ноября 2019

Я работаю над проектом с использованием весенней загрузки с версией 1.3.5. RELEASE, он использует данные весны jpa в качестве постоянного слоя. Я получил задачу реализовать несколько источников данных в этом проекте.

После реализации кода мы получили ошибку, касающуюся этих двух классов сущностей:

@Entity
@Table(name = "TBL_MERCHANT")
public class Merchant implements Serializable {

    @Id
    @Column(name = "ID", length = 14, precision = 14, nullable = false)
    private BigInteger id;

    @Column(name = "NAME", length = 100, nullable = false)
    private String name;

    @JoinColumn(name = "CATEGORY_ID")
    @ManyToOne(fetch = FetchType.LAZY)
    private Categorization categorization;

    @OrderBy("id ASC")
    @ManyToMany(mappedBy = "merchants", fetch = FetchType.LAZY)
    private Set<PaymentMethod> paymentMethods = new HashSet<>();

    @JoinColumn(name = "USER_ID")
    @OneToOne(fetch = FetchType.LAZY)
    private WalletUser user;

// getter setter

и

@Entity
@Table(name = "TBL_PAYMENT_METHOD")
public class PaymentMethod implements Serializable {

    @Id
    @Column(name = "ID", length = 24)
    private String id;

    @Column(name = "DESCRIPTION", length = 255, nullable = true)
    private String desc;

    @ManyToMany
    private Set<Merchant> merchants = new HashSet<>();

// getter setter
}

ранее отношения между этими двумя объектами генерировали таблицу с именем tbl_payment_method_merchants , но после изменений произошла ошибка такого рода ОШИБКА: отношение "tbl_payment_method_tbl_merchant" не существует

мои изменения следующие:

До

@EnableAsync
@EnableAutoConfiguration(exclude = {org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration.class})
@EntityScan("com.somepackage")
@ComponentScan({"com.somepackage})

@EnableJpaRepositories("com.somepackage")
@PropertySource(value = "classpath:stringMessage.properties")
public class MainApplication {

    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);
    }

}

я разделяю его на два разных источника данных, как показано ниже:

После:

сначалаисточник данных:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    basePackages = RepositoryMetadataProvider.REPOSITORY_BASE_PACKAGE,
        includeFilters = @ComponentScan.Filter(ReadOnlyConnection.class),
        entityManagerFactoryRef = ReadOnlyRepositoryConfig.READ_ONLY_ENTITY_MANAGER_FACTORY,
        transactionManagerRef = ReadOnlyRepositoryConfig.READ_ONLY_TRX_MANAGER
)
public class ReadOnlyRepositoryConfig {

    public static final String READ_ONLY_TRX_MANAGER ="readOnlyTransactionManager";
    public static final String READ_ONLY_ENTITY_MANAGER ="readOnlyEntityManager";
    public static final String READ_ONLY_ENTITY_MANAGER_FACTORY ="readOnlyEntityManagerFactory";

    @Bean(name = READ_ONLY_TRX_MANAGER)
    PlatformTransactionManager readOnlyTransactionManager(
            @Qualifier(READ_ONLY_ENTITY_MANAGER_FACTORY) EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    @Bean(name = READ_ONLY_ENTITY_MANAGER)
    EntityManager readOnlyEntityManager(@Qualifier(READ_ONLY_ENTITY_MANAGER_FACTORY) LocalContainerEntityManagerFactoryBean masterEntityFactory) {
        return masterEntityFactory.getObject().createEntityManager();
    }

    @Singleton
    @Bean(name = READ_ONLY_ENTITY_MANAGER_FACTORY)
    LocalContainerEntityManagerFactoryBean readOnlyEntityFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier(DataSourceConfig.WALLET_SLAVE_DATASOURCE) DataSource dataSource) {

        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = builder
                .dataSource(dataSource)
                .packages(RepositoryMetadataProvider.REPOSITORY_BASE_PACKAGE)
                .build();
        localContainerEntityManagerFactoryBean.setMappingResources(new String[]{"META-INF/orm.xml", "META-INF/bv-orm.xml", "META-INF/infinitium-orm.xml", "META-INF/cam-orm.xml"});
        return localContainerEntityManagerFactoryBean;

    }
}

второй источник данных:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = RepositoryMetadataProvider.REPOSITORY_BASE_PACKAGE,
        excludeFilters =@ComponentScan.Filter(ReadOnlyConnection.class),
        entityManagerFactoryRef = TransactionalRepositoryConfig.TRANSACTIONAL_ENTITY_MANAGER_FACTORY,
        transactionManagerRef = TransactionalRepositoryConfig.TRANSACTIONAL_TRX_MANAGER
)
public class TransactionalRepositoryConfig {

    public static final String TRANSACTIONAL_TRX_MANAGER ="transactionalTransactionManager";
    public static final String TRANSACTIONAL_ENTITY_MANAGER ="transactionalEntityManager";
    public static final String TRANSACTIONAL_ENTITY_MANAGER_FACTORY ="transactionalEntityManagerFactory";

    @Primary
    @Bean(name = TRANSACTIONAL_TRX_MANAGER)
    PlatformTransactionManager masterTransactionManager(
            @Qualifier(TRANSACTIONAL_ENTITY_MANAGER_FACTORY) EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }


    @Primary
    @Bean(name = TRANSACTIONAL_ENTITY_MANAGER)
    EntityManager masterEntityManager(@Qualifier(TRANSACTIONAL_ENTITY_MANAGER_FACTORY) LocalContainerEntityManagerFactoryBean masterEntityFactory){
        return masterEntityFactory.getObject().createEntityManager();
    }


    @Singleton
    @Primary
    @Bean(name = TRANSACTIONAL_ENTITY_MANAGER_FACTORY)
    LocalContainerEntityManagerFactoryBean masterEntityFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier(DataSourceConfig.WALLET_MASTER_DATASOURCE) DataSource dataSource) {

        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = builder
                .dataSource(dataSource)
                .packages(RepositoryMetadataProvider.REPOSITORY_BASE_PACKAGE)
                .build();

        localContainerEntityManagerFactoryBean.setMappingResources(new String[]{"META-INF/orm.xml", "META-INF/bv-orm.xml", "META-INF/infinitium-orm.xml", "META-INF/cam-orm.xml"});
        return localContainerEntityManagerFactoryBean;

    }

}

org.hibernate.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "tbl_payment_method_tbl_merchant" не существует при использовании нескольких источников данных

1 Ответ

0 голосов
/ 05 ноября 2019
@Entity
@Table(name = "TBL_MERCHANT")
public class Merchant implements Serializable {

    @OrderBy("id ASC")
    @ManyToMany(mappedBy = "merchants", fetch = FetchType.LAZY)
    @JoinTable(name = "tbl_payment_method_merchants",
        joinColumns = @JoinColumn(name = "idMerchant", referencedColumnName = "idMerchant"),
        inverseJoinColumns = @JoinColumn(name = "idPaymentMethod", referencedColumnName = "idPaymentMethod"))
    private Set<PaymentMethod> paymentMethods = new HashSet<>();

// getter setter

@Entity
@Table(name = "TBL_PAYMENT_METHOD")
public class PaymentMethod implements Serializable {

    @ManyToMany
    @JoinTable(name = "tbl_payment_method_merchants",
        joinColumns = @JoinColumn(name = "idPaymentMethod", referencedColumnName = "idPaymentMethod"),
        inverseJoinColumns = @JoinColumn(name = "idMerchant", referencedColumnName = "idMerchant"))
    private Set<Merchant> merchants = new HashSet<>();

// getter setter
}

Можете ли вы попробовать выше. Это обеспечит доступность метаданных для отношения многие ко многим для обеих сущностей.

Я также предлагаю заменить FetchType.EAGER на FetchType.LAZY.

...