2015-10-12 18 views
13

Stavo usando Google guice nel mio progetto e ora ho provato a convertire totalmente il framework in SpringBoot.Spring boot - configure EntityManager

Ho configurato il fagiolo per persistence.xml come di seguito nella

@Autowired 
@Bean(name = "transactionManager") 
public LocalContainerEntityManagerFactoryBean entityManagerFactory() 
{ 
    LocalContainerEntityManagerFactoryBean lEMF = new LocalContainerEntityManagerFactoryBean(); 
    lEMF.setPersistenceUnitName("leaseManagementPU"); 
    lEMF.setPersistenceXmlLocation("persistence.xml"); 
    return lEMF; 
} 

Ora ho bisogno di configurare (Inject) EntityManager em, a fare operazioni JPA come em.persist(), ecc .. em.find Come configurare, anche qualcuno cerca di spiegarlo con il codice di esempio

risposta

27

Con Spring Boot non è necessario avere alcun file di configurazione come persistence.xml. È possibile configurare con annotations Basta configurare il config DB per APP nei

application.properties

spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver 
spring.datasource.url=jdbc:oracle:thin:@DB... 
spring.datasource.username=username 
spring.datasource.password=pass 

spring.jpa.database-platform=org.hibernate.dialect.... 
spring.jpa.show-sql=true 

Quindi è possibile utilizzare CrudRepository fornito da primavera in cui si dispone di CRUD metodi di transazione standard. Qui puoi anche implementare il tuo SQL's come JPQL.

@Transactional 
public interface ObjectRepository extends CrudRepository<Object, Long> { 
... 
} 

E se ancora necessario utilizzare il Entity Manager è possibile creare un'altra classe.

public class ObjectRepositoryImpl implements ObjectCustomMethods{ 

    @PersistenceContext 
    private EntityManager em; 

} 

Questo dovrebbe essere nella vostra pom.xml

<parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.2.5.RELEASE</version> 
    </parent> 

    <dependencies> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
     </dependency> 


     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-orm</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-core</artifactId> 
      <version>4.3.11.Final</version> 
     </dependency> 
+0

Grazie, È possibile utilizzare JPARepository al posto del repository CRUD. qual è il diff –

+0

Penso che questo non dovrebbe essere un problema. [Qui] (http://docs.spring.io/spring-data/jpa/docs/1.3.0.RELEASE/reference/html/jpa.repositories.html) è una buona documentazione. – Patrick

+1

@Patrick cosa succede se ci sono origini dati personalizzate che si connettono a database diversi. In tal caso non avresti bisogno di usare gestori di entità separate? Come si passerebbe in proprietà di ibernazione in questo caso? – user3869813

12

Hmmm si possono trovare molti esempi per la configurazione di Spring Framework. Comunque qui è un campione

@Configuration 
@Import({PersistenceConfig.class}) 
@ComponentScan(basePackageClasses = { 
    ServiceMarker.class, 
    RepositoryMarker.class } 
) 
public class AppConfig { 

} 

PersistenceConfig

@Configuration 
@PropertySource(value = { "classpath:database/jdbc.properties" }) 
@EnableTransactionManagement 
public class PersistenceConfig { 

    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect"; 
    private static final String PROPERTY_NAME_HIBERNATE_MAX_FETCH_DEPTH = "hibernate.max_fetch_depth"; 
    private static final String PROPERTY_NAME_HIBERNATE_JDBC_FETCH_SIZE = "hibernate.jdbc.fetch_size"; 
    private static final String PROPERTY_NAME_HIBERNATE_JDBC_BATCH_SIZE = "hibernate.jdbc.batch_size"; 
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql"; 
    private static final String[] ENTITYMANAGER_PACKAGES_TO_SCAN = {"a.b.c.entities", "a.b.c.converters"}; 

    @Autowired 
    private Environment env; 

    @Bean(destroyMethod = "close") 
    public DataSource dataSource() { 
     BasicDataSource dataSource = new BasicDataSource(); 
     dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); 
     dataSource.setUrl(env.getProperty("jdbc.url")); 
     dataSource.setUsername(env.getProperty("jdbc.username")); 
     dataSource.setPassword(env.getProperty("jdbc.password")); 
     return dataSource; 
    } 

    @Bean 
    public JpaTransactionManager jpaTransactionManager() { 
     JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject()); 
     return transactionManager; 
    } 

    private HibernateJpaVendorAdapter vendorAdaptor() { 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
     vendorAdapter.setShowSql(true); 
     return vendorAdapter; 
    } 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { 

     LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
     entityManagerFactoryBean.setJpaVendorAdapter(vendorAdaptor()); 
     entityManagerFactoryBean.setDataSource(dataSource()); 
     entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); 
     entityManagerFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);    
     entityManagerFactoryBean.setJpaProperties(jpaHibernateProperties()); 

     return entityManagerFactoryBean; 
    } 

    private Properties jpaHibernateProperties() { 

     Properties properties = new Properties(); 

     properties.put(PROPERTY_NAME_HIBERNATE_MAX_FETCH_DEPTH, env.getProperty(PROPERTY_NAME_HIBERNATE_MAX_FETCH_DEPTH)); 
     properties.put(PROPERTY_NAME_HIBERNATE_JDBC_FETCH_SIZE, env.getProperty(PROPERTY_NAME_HIBERNATE_JDBC_FETCH_SIZE)); 
     properties.put(PROPERTY_NAME_HIBERNATE_JDBC_BATCH_SIZE, env.getProperty(PROPERTY_NAME_HIBERNATE_JDBC_BATCH_SIZE)); 
     properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL)); 

     properties.put(AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "none"); 
     properties.put(AvailableSettings.USE_CLASS_ENHANCER, "false");  
     return properties;  
    } 

} 

principale

public static void main(String[] args) { 
    try (GenericApplicationContext springContext = new AnnotationConfigApplicationContext(AppConfig.class)) { 
     MyService myService = springContext.getBean(MyServiceImpl.class); 
     try { 
      myService.handleProcess(fromDate, toDate); 
     } catch (Exception e) { 
      logger.error("Exception occurs", e); 
      myService.handleException(fromDate, toDate, e); 
     } 
    } catch (Exception e) { 
     logger.error("Exception occurs in loading Spring context: ", e); 
    } 
} 

MyService

@Service 
public class MyServiceImpl implements MyService { 

    @Inject 
    private MyDao myDao; 

    @Override 
    public void handleProcess(String fromDate, String toDate) { 
     List<Student> myList = myDao.select(fromDate, toDate); 
    } 
} 

MyDoaImpl

012.
@Repository 
@Transactional 
public class MyDaoImpl implements MyDao { 

    @PersistenceContext 
    private EntityManager entityManager; 

    public Student select(String fromDate, String toDate){ 

     TypedQuery<Student> query = entityManager.createNamedQuery("Student.findByKey", Student.class); 
     query.setParameter("fromDate", fromDate); 
     query.setParameter("toDate", toDate); 
     List<Student> list = query.getResultList(); 
     return CollectionUtils.isEmpty(list) ? null : list; 
    } 

} 

Assumendo progetto Maven: file di Proprietà dovrebbe essere nella cartella di file di src/main/recourses/database

jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver 
jdbc.url=your db url 
jdbc.username=your Username 
jdbc.password=Your password 

hibernate.max_fetch_depth = 3 
hibernate.jdbc.fetch_size = 50 
hibernate.jdbc.batch_size = 10 
hibernate.show_sql = true 

ServiceMarker e RepositoryMarker sono interfacce solo vuoti nel vostro servizio o del pacchetto impl repository.

Supponiamo di avere il nome del pacchetto a.b.c.service.impl. MyServiceImpl è in questo pacchetto e anche ServiceMarker.

public interface ServiceMarker { 

} 

Stesso contrassegno di ripetizione. Supponiamo che tu abbia il nome del pacchetto a.b.c.repository.impl o a.b.c.dao.impl.Poi MyDaoImpl è in questo pacchetto e anche Repositorymarker

public interface RepositoryMarker { 

} 

abcentities.Student

//dummy class and dummy query 
@Entity 
@NamedQueries({ 
@NamedQuery(name="Student.findByKey", query="select s from Student s where s.fromDate=:fromDate" and s.toDate = :toDate) 
}) 
public class Student implements Serializable { 

    private LocalDateTime fromDate; 
    private LocalDateTime toDate; 

    //getters setters 

} 

abcconverters

@Converter(autoApply = true) 
public class LocalDateTimeConverter implements AttributeConverter<LocalDateTime, Timestamp> { 

    @Override 
    public Timestamp convertToDatabaseColumn(LocalDateTime dateTime) { 

     if (dateTime == null) { 
      return null; 
     } 
     return Timestamp.valueOf(dateTime); 
    } 

    @Override 
    public LocalDateTime convertToEntityAttribute(Timestamp timestamp) { 

     if (timestamp == null) { 
      return null; 
     }  
     return timestamp.toLocalDateTime(); 
    } 
} 

pom.xml

<properties> 
    <java-version>1.8</java-version> 
    <org.springframework-version>4.2.1.RELEASE</org.springframework-version> 
    <hibernate-entitymanager.version>5.0.2.Final</hibernate-entitymanager.version> 
    <commons-dbcp2.version>2.1.1</commons-dbcp2.version> 
    <mysql-connector-java.version>5.1.36</mysql-connector-java.version> 
    <junit.version>4.12</junit.version> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>${junit.version}</version> 
     <scope>test</scope> 
    </dependency> 

    <!-- Spring --> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-context</artifactId> 
     <version>${org.springframework.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-jdbc</artifactId> 
     <version>${org.springframework.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>javax.inject</groupId> 
     <artifactId>javax.inject</artifactId> 
     <version>1</version> 
     <scope>compile</scope> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-tx</artifactId> 
     <version>${org.springframework-version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-orm</artifactId> 
     <version>${org.springframework-version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>${hibernate-entitymanager.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>mysql</groupId> 
     <artifactId>mysql-connector-java</artifactId> 
     <version>${mysql-connector-java.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.apache.commons</groupId> 
     <artifactId>commons-dbcp2</artifactId> 
     <version>${commons-dbcp2.version}</version> 
    </dependency> 
</dependencies> 

<build> 
    <finalName>${project.artifactId}</finalName> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <version>3.3</version> 
      <configuration> 
       <source>${java-version}</source> 
       <target>${java-version}</target> 
       <compilerArgument>-Xlint:all</compilerArgument> 
       <showWarnings>true</showWarnings> 
       <showDeprecation>true</showDeprecation> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

Speranza che aiuta . Grazie

+1

Grazie Basti mi ha aiutato molto –

+0

Il mio piacere :) Puoi anche utilizzare Spring Data JPA nel tuo progetto. In questo modo non devi scrivere semplici query sulle tue classi di dominio. Inoltre semplificherà ulteriormente la tua applicazione. Segui questo link https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods – Basit

+0

Che bello - finalmente una documentazione su come farlo! Solo una domanda, che affronterò ora che è chiaro come arrivare a questo punto: come si codifica senza alcuna dipendenza hard-coded sulle classi di driver JDBC e le classi del pool di connessioni? – Adam