2012-03-13 6 views
7

Quiero llenar algunas tablas de mi base de datos desde un archivo de texto en el inicio, quiero que se llame a mi método de inicialización solo cuando se inicia mi aplicación.Spring Web Application: hacer algo al inicio (inicialización)

Estoy usando Spring (+ MVC) e Hibernate con MySQL.

¿cómo puedo hacer?

+0

posible duplicado de [inicialización de la aplicación web surgen de la base de datos en el arranque] (http://stackoverflow.com/questions/ 7082594/spring-web-application-initialization-from-database-on-startup) –

+1

@Tomasz Nurkiewicz: no es un duplicado de http://stackoverflow.com/questions/7082594/spring-web-application-initialization-from -database-on-startup, porque el flujo de información es al revés, por lo que se podrían utilizar otras formas de resolver el problema. – Ralph

+0

Es muy similar. El mío es un poco más genérico. –

Respuesta

5

Utilice la anotación postconstuct algún lugar dentro de un grano:

@PostConstruct 
public void init() { 
    //startup logic here 
} 

probablemente tiene sentido (desgin) para utilizar un grano de configuración, pero puede ser cualquier frijol en absoluto.

+0

Ok, la forma correcta puede ser hacer un "Iniciador" singleton y @PostConstruct un método? ¡Gracias! :) –

+0

Esto no funciona para iniciar AsyncTasks. Use la recomendación de sinuhepop a continuación - http://stackoverflow.com/a/9680800/1019307 – HankCa

7

Hibernate viene con una forma de agregar algunos archivos con sentencias SQL que se ejecutarán al inicio.

El parámetro es hibernate.hbm2ddl.import_files.

@see Hibernate Reference: Chapter 3.4. Optional configuration properties

  • Tabla 3.7. Propiedades Varios
  • hibernate.hbm2ddl.import_files:

nombres separados por comas de los archivos opcionales que contienen SQL DML instrucciones ejecutadas durante la creación SessionFactory. Esto es útil para pruebas o demostraciones: al agregar las instrucciones INSERT, por ejemplo, puede llenar su base de datos con un conjunto mínimo de datos cuando se implementa .

La orden del archivo importa, las instrucciones de un archivo de entrega se ejecutan antes de las declaraciones de los siguientes archivos. Estas instrucciones solo se ejecutan en si se crea el esquema, es decir, si hibernate.hbm2ddl.auto se establece en para crear o crear-soltar.

p. Ej. /humans.sql,/dogs.sql

me gustan algunos indicios de que esto sólo puede funcionar si hibernación se inicia en modo 'crear'. Pero no estoy seguro.

+0

muy útil. No es la respuesta a la pregunta en sí, pero ... ¡ESO es justo lo que necesito! ¡GRACIAS! Sin embargo, no puedo hacer que los archivos import_files funcionen :(En lugar de poner un "import.sql" en mi classpath, ¡se ejecuta perfectamente! –

16

Puede crear un oyente de aplicaciones, está diseñado específicamente para tales necesidades. En este caso, se ejecutará cada vez que se inicie (o actualice) el contexto.

@Component 
public class DatabaseFillerOnStartup implements ApplicationListener<ContextRefreshedEvent> { 
    @Override 
    public void onApplicationEvent(ContextRefreshedEvent event) { 
     ... 
    } 
} 
+0

útil, gracias :) –

+0

Exactamente lo que estaba buscando para hacer un autodiagnóstico . ¡Gracias! – Marquee

+0

Esta debería ser la respuesta ... :) –

0

dos opciones,

Primero: Vamos a crear su hibernación cada ddl los servicios es el inicio (Sólo para el medio ambiente local o dev)

<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" 
     p:showSql="false" 
     p:generateDdl="true"/> 

O crear en primavera con un Bean INIT- perezoso falso y agregue allí la lógica para crear la base de datos si no la tiene o no la inyecte, o haga lo que quiera.

<bean id="bootstrapStartup" class="com.tscompany.rest.bootstrap.BootstrapStartup" lazy-init="false" init-method="init"/> 
0

Usted puede crear un poco de frijol en la configuración de la raíz del contexto - como

<bean id="someBean" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="someProperty"> 
     ... description of the property 
    </property> 
    <property name="targetMethod" value="methodName" /> 
</bean> 

Por lo tanto - en el método de inicio de la aplicación "methodName" será invocado. Tenemos actualizaciones de DB implementadas de tal manera.

0

Si ha establecido su propiedad hibernate.hbm2ddl.auto a create o create-drop entonces la manera más fácil de hacer esto es mediante el establecimiento de hibernate.hbm2ddl.import_files propiedad con el nombre del archivo SQL que contiene sentencias SQL para cargar los datos iniciales en el esquema de la base, por ejemplo, usuarios iniciales de la aplicación.

El siguiente es un método de ejemplo que tengo en mi clase DatabaseConfig. Establece la propiedad hibernate.hbm2ddl.import_files con el nombre de archivo SQL import_initial_data.sql que contiene instrucciones SQL Insert para cargar mis datos iniciales en el esquema de la base de datos.

@Bean 
    public LocalSessionFactoryBean hibernate5SessionFactoryBean(){ 
     LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean(); 
     localSessionFactoryBean.setDataSource((DataSource) appContext.getBean("DataSource")); 
     localSessionFactoryBean.setAnnotatedClasses(AppUser.class); 
     Properties properties = new Properties(); 
     properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); 
     properties.put("hibernate.hbm2ddl.auto","create-drop"); 
     properties.put("hibernate.hbm2ddl.import_files", "import_initial_data.sql"); 
     properties.put("hibernate.show_sql","true"); 
     localSessionFactoryBean.setHibernateProperties(properties); 
     return localSessionFactoryBean; 
    } 

Este es mi paquete AppUser.java en model:

package com.beniregev.model; 

import lombok.AccessLevel; 
import lombok.AllArgsConstructor; 
import lombok.NoArgsConstructor; 
import javax.persistence.*; 

@Entity 
@NoArgsConstructor(access = AccessLevel.PUBLIC) 
@AllArgsConstructor(access = AccessLevel.PUBLIC) 
public class AppUser { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 
    @Column(nullable = false, unique = true) 
    private String userName; 
    @Column(nullable = false) 
    private String password; 

    public AppUser(String userName, String password) { 
     this.userName = userName; 
     this.password = password; 
    } 
} 

Maven dependencia para Lombok:

<dependency> 
    <groupId>org.projectlombok</groupId> 
    <artifactId>lombok</artifactId> 
    <version>1.16.6</version> 
    <scope>provided</scope> 
</dependency> 

El archivo import_initial_data.sql que tengo en resources directorio:

INSERT INTO appuser(username, password) VALUES ('jesus', 'christ'); 
INSERT INTO appuser(username, password) VALUES ('mary', 'virgin'); 
INSERT INTO appuser(username, password) VALUES ('josef', 'who?'); 
INSERT INTO appuser(username, password) VALUES ('jeremaia', 'profet'); 
COMMIT; 

Y el resultado de SELECT * * FROM appuser; *:

Resultset of SELECT * FROM appuser;

Cuestiones relacionadas