![](/img/trans.png)
[英]Execute stored procedures with multiple parameters and map ResultSet to non-entity class using spring data jpa
[英]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 實體管理器會在兩個控制器中自動裝配。
我認為,您可以分別在CardReports
和MemberDaily
控制器中嘗試使用@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.