制作多个 EntityManager(Spring-Boot-JPA、Hibernate、MSSQL)
Posted
技术标签:
【中文标题】制作多个 EntityManager(Spring-Boot-JPA、Hibernate、MSSQL)【英文标题】:Making Multiple EntityManagers (Spring-Boot-JPA, Hibernate, MSSQL) 【发布时间】:2015-10-20 04:51:41 【问题描述】:我想连接到 2 个不同的数据库(MSSQL)。所以我喜欢下面。虽然我的 ProductController
有效,但 CustomerController
无效。添加客户控制器后,spring boot应用程序无法启动,因为它无法@Autowire
CustomerDAO
。
这里出了什么问题,我该如何解决?
我所做的如下所示,
application.properties
DatabaseIP=myip
DatabasePort=1433
DB1DatabaseName=Test
DB2DatabaseName=Test2
DatabaseUser=sa
DatabasePwd=boomboom
#DB1
datasource.db1.url=jdbc:sqlserver://$DatabaseIP:$DatabasePort;databaseName=$DB1DatabaseName
datasource.db1.username=$DatabaseUser
datasource.db1.password=$DatabasePwd
datasource.db1.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
datasource.db2.url=jdbc:sqlserver://$DatabaseIP:$DatabasePort;databaseName=$DB2DatabaseName
datasource.db2.username=$DatabaseUser
datasource.db2.password=$DatabasePwd
datasource.db2.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.EJB3NamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
spring.jpa.show-sql=true
security.user.name=raj
security.user.password=raj123456
DB1EntityManager.java
@Configuration
@EnableTransactionManagement
@EnableAutoConfiguration
@EntityScan(basePackages = "com.rajkishan.db1Entities")
@EnableJpaRepositories(transactionManagerRef = "db1TransactionManager", entityManagerFactoryRef = "db1EntityManagerFactory", basePackages = "com.rajkishan.db1DAOs")
public class DB1EntityManager
@Bean(name = "db1DataSource")
@Primary
@ConfigurationProperties(prefix = "datasource.db1")
public DataSource db1DataSource()
return DataSourceBuilder.create().build();
@Bean(name = "db1EntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean db1EntityManagerFactory(final EntityManagerFactoryBuilder builder)
return builder
.dataSource(db1DataSource())
.build();
@Bean(name = "db1TransactionManager")
@Primary
public JpaTransactionManager db1TransactionManager(@Qualifier("db1EntityManagerFactory") final EntityManagerFactory emf)
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
ProductDAO.java
@Transactional("db1TransactionManager")
public interface ProductDAO extends CrudRepository<Product, String>
ProductController.java
@RestController
@RequestMapping(value = "/product")
public class ProductController
@Autowired
private EntityManager em;
@Autowired
private ProductDAO productDAO;
@RequestMapping(value = "/getinfo", method = RequestMethod.GET)
public String getProductInfo(@RequestParam(value = "model") String model)
try
Product product = productDAO.findOne(model);
if (product == null)
return "No Data Found";
String userName = "Maker for Model = " + model + " is "
+ product.getMaker()+ " and Type = " + product.getType();
return userName;
catch (Exception ex)
System.out.println(ex);
return "Error Occured";
DB2EntityManager.java
@Configuration
@EnableTransactionManagement
@EntityScan(basePackages = "com.rajkishan.db2Entities")
@EnableJpaRepositories(transactionManagerRef = "db2TransactionManager", entityManagerFactoryRef = "db2EntityManagerFactory", basePackages = "com.rajkishan.db2DAOs")
public class DB2EntityManager
@Bean(name = "db2DataSource")
@ConfigurationProperties(prefix = "datasource.db2")
public DataSource db2DataSource()
return DataSourceBuilder.create().build();
@Bean(name = "db2EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean db2EntityManagerFactory(final EntityManagerFactoryBuilder builder)
return builder
.dataSource(db2DataSource())
.build();
@Bean(name = "db2TransactionManager")
public JpaTransactionManager db2TransactionManager(@Qualifier("db2EntityManagerFactory") final EntityManagerFactory emf)
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
CustomerDAO.java
@Transactional("db2TransactionManager")
public interface CustomersDAO extends CrudRepository<Customers, Integer>
CustomerController.java
@RestController
@RequestMapping(value = "/customer")
public class CustomerController
@Autowired
private CustomersDAO customersDAO;
@Autowired
private EntityManager em;
@RequestMapping(value = "/getcustomerinfo", method = RequestMethod.GET)
public String getCustomerInfo(@RequestParam(value = "customerid") int cusId)
try
Customers customer = customersDAO.findOne(cusId);
if (customer == null)
return "No Data Found";
String userName = "Name of Customer with CustomerID = " + cusId + " is "
+ customer.getFirstName()+ " " + customer.getLastName() + " and his AddressID = " + customer.getAddressId();
return userName;
catch (Exception ex)
System.out.println(ex);
return "Error Occured";
错误日志
2015-07-29 14:29:53.834 INFO 4976 --- [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default...]
2015-07-29 14:29:54.146 INFO 4976 --- [main] org.hibernate.dialect.Dialect: HHH000400: Using dialect:org.hibernate.dialect.SQLServerDialect
2015-07-29 14:29:54.167 INFO 4976 --- [main]o.h.h.i.ast.ASTQueryTranslatorFactory: HHH000397: Using ASTQueryTranslatorFactory
2015-07-29 14:29:54.262 WARN 4976 --- [main] o.h.j.i.EntityManagerFactoryRegistry: HHH000436: Entity manager factory name(default) is already
registered. If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'
2015-07-29 14:29:54.571 WARN 4976 --- [main]ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancel
ling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerController': Injection of autowired dependencies failed; nested
exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.rajkishan.db2DAOs.CustomersDAO com.rajkishan.control
lers.CustomerController.customersDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customersDAO':
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.rajkishan.db2Entities.Customers
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java
:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at com.rajkishan.Application.main(Application.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.rajkishan.db2DAOs.CustomersDAO com.rajkishan.controlle
rs.CustomerController.customersDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customersDAO': I
nvocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.rajkishan.db2Entities.Customers
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.j
ava:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java
:331)
... 22 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customersDAO': Invocation of init method failed; nested excep
tion is java.lang.IllegalArgumentException: Not an managed type: class com.rajkishan.db2Entities.Customers
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.j
ava:533)
... 24 common frames omitted
Customers.java
@Entity
@Table(name = "Customers", catalog = "Test2", schema = "dbo")
@XmlRootElement
@NamedQueries(
@NamedQuery(name = "Customers.findAll", query = "SELECT c FROM Customers c"),
@NamedQuery(name = "Customers.findById", query = "SELECT c FROM Customers c WHERE c.id = :id"),
@NamedQuery(name = "Customers.findByFirstName", query = "SELECT c FROM Customers c WHERE c.firstName = :firstName"),
@NamedQuery(name = "Customers.findByLastName", query = "SELECT c FROM Customers c WHERE c.lastName = :lastName"))
public class Customers implements Serializable
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "Id")
private Integer id;
@Size(max = 255)
@Column(name = "first_name")
private String firstName;
@Size(max = 255)
@Column(name = "last_name")
private String lastName;
@JoinColumn(name = "AddressId", referencedColumnName = "AddressId")
@ManyToOne(optional = false)
private Address addressId;
public Customers()
public Customers(Integer id)
this.id = id;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getFirstName()
return firstName;
public void setFirstName(String firstName)
this.firstName = firstName;
public String getLastName()
return lastName;
public void setLastName(String lastName)
this.lastName = lastName;
public Address getAddressId()
return addressId;
public void setAddressId(Address addressId)
this.addressId = addressId;
@Override
public int hashCode()
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
@Override
public boolean equals(Object object)
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Customers))
return false;
Customers other = (Customers) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id)))
return false;
return true;
@Override
public String toString()
return "com.rajkishan.db2Entities.Customers[ id=" + id + " ]";
【问题讨论】:
为自动装配的依赖注入失败提供堆栈跟踪。如果它太长并且你不能剥离必需品,也许可以放一个链接 @LaurentiuL.:发布了堆栈跟踪。问题已更新。 CustomerDAO 是否在 com.rajkishan.db2DAOs 中? 发布您的客户类代码。我对注释感兴趣。我假设它在 com.rajkishan.db2Entities.Customers @LaurentiuL。 : 它是一个生成的实体类。问题已更新。 【参考方案1】:在DAO类上添加@Repository
注解,让spring知道它们。如下所示;
@Repository
@Transactional("db2TransactionManager")
public interface CustomersDAO extends CrudRepository<Customers, Integer>
【讨论】:
以上是关于制作多个 EntityManager(Spring-Boot-JPA、Hibernate、MSSQL)的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 中获取 EntityManager 的句柄