簡體   English   中英

Spring 數據 JPA map 存儲過程結果從多個數據源到非實體 POJO

[英]Spring Data JPA map the stored procedure result to Non-Entity POJO from multiple data source

我試圖研究在兩個不同的數據源上調用兩個存儲過程的更好方法,但沒有成功。 這是我的場景,我連接到兩個數據源,每個數據源都有一個存儲過程。 每當我將一個配置注釋為主要配置時,我都會得到結果,另一個未映射為主要配置的配置會引發錯誤

給定的 SqlResultSetMapping 名稱 [Unknown SqlResultSetMapping [Testing]] 未知

當我為 class 設置其他配置時,將存儲過程調用為主,它顯示結果,但是當它們都沒有設置為主時,它們會拋出錯誤

給定的 SqlResultSetMapping 名稱 [Unknown SqlResultSetMapping [Testing]] 未知

卡了好幾天。 我將不勝感激。在此先感謝您

我調用第一個數據源的第一個配置

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "guru.springframework.multipledatasources.model.Card",
        entityManagerFactoryRef = "cardEntityManagerFactory",
        transactionManagerRef= "cardTransactionManager")
public class Cardonfiguration {

        @Bean
        @Primary
        @ConfigurationProperties("datasource.card")
        public DataSourceProperties cardDataSourceProperties() {
            return new DataSourceProperties();
        }

        @Bean
        @Primary
        @ConfigurationProperties("datasource.card.configuration")
        public DataSource cardDataSource() {
            return cardDataSourceProperties().initializeDataSourceBuilder()
                    .type(BasicDataSource.class).build();
        }

        @Primary
        @Bean(name = "cardEntityManagerFactory")
        public LocalContainerEntityManagerFactoryBean cardEntityManagerFactory(
                EntityManagerFactoryBuilder builder) {
            return builder
                    .dataSource(cardDataSource())
                    .packages(Card.class)
                    .build();
        }

        @Primary
        @Bean
        public PlatformTransactionManager cardTransactionManager(
                final @Qualifier("cardEntityManagerFactory") LocalContainerEntityManagerFactoryBean cardEntityManagerFactory) {
            return new JpaTransactionManager(Objects.requireNonNull(cardEntityManagerFactory.getObject()));
    }
}

我對第二個數據源的第二個配置

@Configuration
@EnableJpaRepositories(basePackages = "guru.springframework.multipledatasources.model.member",
        entityManagerFactoryRef = "memberEntityManagerFactory",
        transactionManagerRef= "memberTransactionManager")
public class MemberConfiguration {
    @Bean
    @ConfigurationProperties("datasource.member")
    public DataSourceProperties zamphiaDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("datasource.member.configuration")
    public DataSource memberDataSource() {
        return memberDataSourceProperties().initializeDataSourceBuilder()
                .type(BasicDataSource.class).build();
    }

    @Bean(name = "memberEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean memberEntityManagerFactory(
            EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(memberDataSource())
                .packages(member.class)
                .build();
    }

    @Bean
    public PlatformTransactionManager memberTransactionManager(
            final @Qualifier("memberEntityManagerFactory") LocalContainerEntityManagerFactoryBean memberEntityManagerFactory) {
        return new JpaTransactionManager(memberEntityManagerFactory.getObject());
    }

}

我的 controller 作為第一個數據源

@RequestMapping("/api/v1")
@RestController
public class CardReports {

    @PersistenceContext
    private EntityManager entityManager;

    @SuppressWarnings("unchecked")
    @RequestMapping("/reports/CARD/dailyreport")
    public List<Testing> getDailyAchievements(){
        List<Testing> list;
        StoredProcedureQuery query = entityManager.createStoredProcedureQuery("dailyreports", "Testing");
        try {
            // Execute query
            query.execute();
            list = query.getResultList();
        } finally {
            try {
                query.unwrap(ProcedureOutputs.class).release();
            } catch (Exception e) {
            }
        }
        return list;
    }
}

我的第一個數據源的非實體

@MappedSuperclass
@SqlResultSetMapping(name = "Testing", classes = @ConstructorResult(targetClass = Testing.class, columns = {
        @ColumnResult(name = "TTEAM_ID", type = Integer.class),
        @ColumnResult(name = "VDATE", type = String.class),
        @ColumnResult(name="Days_in_Field", type = String.class),
        @ColumnResult(name= "Expected_cummilative_Number_of_HH", type = String.class),
        @ColumnResult(name="Cummlative_HH_Reached", type = String.class),
        @ColumnResult(name="HH_Reached_for_day", type = String.class),
        @ColumnResult(name ="HHs_Finalised_for_day", type = String.class),
        @ColumnResult(name="Number_of_HH_in_process_for_day", type = String.class),
        @ColumnResult(name="Number_of_HH_Refused_for_day", type = String.class),
        @ColumnResult(name="Number_of_Revisits_Scheduled_for_day", type = String.class),
        @ColumnResult(name="HH_loss_3rd_visit_attempt_refusals_for_day", type = String.class)
}))

public class Testing {
    private Integer TTEAM_ID;
    private String  VDATE;
    private String Days_in_Field;
    private String Expected_cummilative_Number_of_HH;
    private String Cummlative_HH_Reached;
    private String HH_Reached_for_day;
    private String HHs_Finalised_for_day;
    private String Number_of_HH_in_process_for_day;
    private String Number_of_HH_Refused_for_day;
    private String Number_of_Revisits_Scheduled_for_day;
    private String HH_loss_3rd_visit_attempt_refusals_for_day;

    public Testing(Integer TTEAM_ID, String VDATE, String Days_in_Field, String Expected_cummilative_Number_of_HH, String Cummlative_HH_Reached, String HH_Reached_for_day, String HHs_Finalised_for_day, String Number_of_HH_in_process_for_day, String Number_of_HH_Refused_for_day, String Number_of_Revisits_Scheduled_for_day, String HH_loss_3rd_visit_attempt_refusals_for_day) {
        this.TTEAM_ID = TTEAM_ID;
        this.VDATE = VDATE;
        this.Days_in_Field = Days_in_Field;
        this.Expected_cummilative_Number_of_HH = Expected_cummilative_Number_of_HH;
        this.Cummlative_HH_Reached = Cummlative_HH_Reached;
        this.HH_Reached_for_day = HH_Reached_for_day;
        this.HHs_Finalised_for_day = HHs_Finalised_for_day;
        this.Number_of_HH_in_process_for_day= Number_of_HH_in_process_for_day;
        this.Number_of_HH_Refused_for_day = Number_of_HH_Refused_for_day;
        this.Number_of_Revisits_Scheduled_for_day = Number_of_Revisits_Scheduled_for_day;
        this.HH_loss_3rd_visit_attempt_refusals_for_day = HH_loss_3rd_visit_attempt_refusals_for_day;
    }
//getters and setters

我的第二個數據源 controller

 @RequestMapping("/api/v1")
    @RestController
    public class MemberDaily {
    
        @PersistenceContext
        private EntityManager entityManager;
    
        @SuppressWarnings("unchecked")
        @RequestMapping("/reports/member/dailyachievementreport")
        public List<DailyReport> getDailyAchievements(){
            List list;
            StoredProcedureQuery query = entityManager.createStoredProcedureQuery("dailyreports", "Testing");
            try {
                // Execute query
                query.execute();
                list = query.getResultList();
            } finally {
                try {
                    query.unwrap(ProcedureOutputs.class).release();
                } catch (Exception e) {
                }
            }
            return list;
        }
    }

我如何在我的 pojo 上為我的第二個數據源映射結果

@MappedSuperclass
    @SqlResultSetMapping(name = "Testing", classes = @ConstructorResult(targetClass = Testing.class, columns = {
            @ColumnResult(name = "TTEAM_ID", type = Integer.class),
            @ColumnResult(name = "VDATE", type = String.class),
            @ColumnResult(name="Days_in_Field", type = String.class),
            @ColumnResult(name= "Expected_cummilative_Number_of_HH", type = String.class),
            @ColumnResult(name="Cummlative_HH_Reached", type = String.class),
            @ColumnResult(name="HH_Reached_for_day", type = String.class),
            @ColumnResult(name ="HHs_Finalised_for_day", type = String.class),
            @ColumnResult(name="Number_of_HH_in_process_for_day", type = String.class),
            @ColumnResult(name="Number_of_HH_Refused_for_day", type = String.class),
            @ColumnResult(name="Number_of_Revisits_Scheduled_for_day", type = String.class),
            @ColumnResult(name="HH_loss_3rd_visit_attempt_refusals_for_day", type = String.class)
    }))
    
    public class Testing {
        private Integer TTEAM_ID;
        private String  VDATE;
        private String Days_in_Field;
        private String Expected_cummilative_Number_of_HH;
        private String Cummlative_HH_Reached;
        private String HH_Reached_for_day;
        private String HHs_Finalised_for_day;
        private String Number_of_HH_in_process_for_day;
        private String Number_of_HH_Refused_for_day;
        private String Number_of_Revisits_Scheduled_for_day;
        private String HH_loss_3rd_visit_attempt_refusals_for_day;
    
        public Testing(Integer TTEAM_ID, String VDATE, String Days_in_Field, String Expected_cummilative_Number_of_HH, String Cummlative_HH_Reached, String HH_Reached_for_day, String HHs_Finalised_for_day, String Number_of_HH_in_process_for_day, String Number_of_HH_Refused_for_day, String Number_of_Revisits_Scheduled_for_day, String HH_loss_3rd_visit_attempt_refusals_for_day) {
            this.TTEAM_ID = TTEAM_ID;
            this.VDATE = VDATE;
            this.Days_in_Field = Days_in_Field;
            this.Expected_cummilative_Number_of_HH = Expected_cummilative_Number_of_HH;
            this.Cummlative_HH_Reached = Cummlative_HH_Reached;
            this.HH_Reached_for_day = HH_Reached_for_day;
            this.HHs_Finalised_for_day = HHs_Finalised_for_day;
            this.Number_of_HH_in_process_for_day= Number_of_HH_in_process_for_day;
            this.Number_of_HH_Refused_for_day = Number_of_HH_Refused_for_day;
            this.Number_of_Revisits_Scheduled_for_day = Number_of_Revisits_Scheduled_for_day;
            this.HH_loss_3rd_visit_attempt_refusals_for_day = HH_loss_3rd_visit_attempt_refusals_for_day;
        }
    //getters and setters

Your cardEntityManagerFactory will scan the package of Card.class for classes annotated with @ManagedSuperClass and memberEntityManagerFactory will scan the package of member.class

看起來您在兩個控制器中都使用帶有SQLResultSetMapping "Testing" 的相同 POJO。 但是不清楚這個POJO在哪個package中。 因此,請確保兩個實體管理器都掃描了 POJO 的 package。

此外,您只需自動連接實體管理器,而無需在兩個控制器中指定名稱。 據我了解,如果您不指定Qualifier ,則只有 Primary 實體管理器會在兩個控制器中自動裝配。

我認為,您可以分別在CardReportsMemberDaily控制器中嘗試使用@PersistenceContext(name = "cardEntityManagerFactory")@PersistenceContext(name = "memberEntityManagerFactory")

更新

我查看了您的 GitHub 代碼,發現您的BAISVReports controller 僅獲得了主要實體管理器。 因此,只需使用@Qualifier自動裝配實體管理器,如下所示,現在輔助實體管理器正在自動裝配。 現在兩個控制器都能夠找到SQLResultSetMapping

@RequestMapping("/api/v1")
@RestController
public class BAISVReports {

@Autowired
@Qualifier("baisvEntityManagerFactory")
private EntityManager entityManager;

有關詳細信息,請參閱 有關如何在 Spring 引導中配置多個數據源、實體管理器、事務管理器的文章

我認為SqlResultSetMapping用於@MappedSuperclass 試着把它放在一個實體上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM