Spring data + JPA + Hibernate - Java SE

7 respostas
vasilvei

Não estou conseguindo configurar Spring em java desktop, alguém pode ver o que estou fazendo de errado, ou tem algum tutorial de como fazer?

segue meu teste:

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="Arena" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>br.com.arena.model.Uf</class>
    <properties>
      <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
      <property name="hibernate.connection.username" value="arena"/>
      <property name="hibernate.connection.password" value="arena"/>
      <property name="hibernate.connection.url" value="jdbc:postgresql://192.168.1.77:5432/arena"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
      <property name="hibernate.show_sql" value="false"/>
      <property name="hibernate.format_sql" value="false"/>
      <!--          <property name="hibernate.hbm2ddl.auto" value="update" /> -->
      <property name="hibernate.c3p0.min_size" value="5"/>
      <property name="hibernate.c3p0.max_size" value="20"/>
      <property name="hibernate.c3p0.timeout" value="300"/>
      <property name="hibernate.c3p0.max_statements" value="50"/>
      <property name="hibernate.c3p0.idle_test_period" value="2000"/>
    </properties>
  </persistence-unit>
</persistence>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

 	<!-- Indica ao spring que as classes estão sendo gerenciadas por annotation -->
    <context:annotation-config />

	<!-- Aonde o spring vai buscar as anotações de classes referente aos componentes do sistema-->
	<context:component-scan base-package="br.com.arena.*" />
	
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="Arena"/>

        <property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="generateDdl" value="true" />
				<property name="database" value="POSTGRESQL" />
			</bean>
		</property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

	<!-- Informar ao spring onde esta as classes de repositorio, para o spring-data fazer a mágica -->
	<jpa:repositories base-package="br.com.arena.repository" />
    
</beans>

UfRepository

package br.com.arena.repository;

import br.com.arena.model.Uf;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 *
 * @author Valde
 */
public interface UfRepository extends JpaRepository<Uf, Long> {
   
}

UfBusiness

@Component
public class UfBusiness {
package br.com.arena.business;

import br.com.arena.model.Uf;
import br.com.arena.repository.UfRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 *
 * @author Valde
 */
@Component
public class UfBusiness {
    @Autowired
    private UfRepository respository;
    

    public void save(){
        Uf uf = new Uf("teste", "teste", "Teste");
        
        respository.save(uf);
    }
}

Uf.java

package br.com.arena.model;

// Generated 22/02/2012 19:55:55 by Hibernate Tools 3.4.0.CR1
import java.util.Objects;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * Uf generated by hbm2java
 */
@Entity
@Table(name = "uf", schema = "coliseusys")
public class Uf implements java.io.Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 5922213257847042108L;
    private String uf;
    private String nomeuf;
    private String paissigla;
    private String siglauf;
  
    public Uf() {
    }

    public Uf(String uf, String nomeuf, String paissigla) {
        this.uf = uf;
        this.nomeuf = nomeuf;
        this.paissigla = paissigla;
    }

    public Uf(String uf, String nomeuf, String paissigla, String siglauf) {
        this.uf = uf;
        this.nomeuf = nomeuf;
        this.paissigla = paissigla;
        this.siglauf = siglauf;
    }

    @Id
    @Column(name = "uf", unique = true, length = 2)
    public String getUf() {
        return this.uf;
    }

    public void setUf(String uf) {
        this.uf = uf;
    }

    @Column(name = "nomeuf", length = 60)
    public String getNomeuf() {
        return this.nomeuf;
    }

    public void setNomeuf(String nomeuf) {
        this.nomeuf = nomeuf;
    }

    @Column(name = "paissigla", length = 2)
    public String getPaissigla() {
        return this.paissigla;
    }

    public void setPaissigla(String paissigla) {
        this.paissigla = paissigla;
    }

    @Column(name = "siglauf", length = 2)
    public String getSiglauf() {
        return this.siglauf;
    }

    public void setSiglauf(String siglauf) {
        this.siglauf = siglauf;
    }

   @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Uf other = (Uf) obj;
        if (!Objects.equals(this.uf, other.uf)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + Objects.hashCode(this.uf);
        return hash;
    }
}

Ufteste.java

package arena;

import br.com.arena.business.UfBusiness;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 * @author Valde
 */
public class Ufteste {

    public Ufteste() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/META-INF/applicationContext.xml");


    }

    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */

        new Ufteste();
        //</editor-fold>
        UfBusiness ufb = new UfBusiness();

        ufb.save();

    }
    /**
     * @param args the command line arguments
     */
}

Erro:

run:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" java.lang.NullPointerException
	at br.com.arena.business.UfBusiness.list(UfBusiness.java:26)
	at arena.Ufteste.main(Ufteste.java:40)
Java Result: 1

7 Respostas

wagnerfrancisco

Cara, como você instanciou o teu UfBusiness com new, acredito que o Spring não consiga injetar o que você precisa nele.

Numa aplicação desktop, acredito que a maneira mais simples seja pedir pro container uma instância de UfBusiness:

UfBusiness ufBusiness = context.getBean(UfBusiness.class);

Vai meio contra a filosofia do Spring, deve ter uma maneira melhor pra fazer isto em aplicações desktop. De qualquer maneira você só faria isso com o UfBusiness, o restante seria injetado.

vasilvei

Obrigado wagnerfrancisco!

se por gentileza poder me explicar melhor ande eu colocaria esse seu exemplo…

eu sou meio novato nisso!

vasilvei

A entendi:

public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */

         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/META-INF/applicationContext.xml");
         UfBusiness ufBusiness = applicationContext.getBean(UfBusiness.class);
       
        //</editor-fold>
        //UfBusiness ufb = new UfBusiness();

       ufBusiness.save();

    }
vasilvei

Deu certo…

Mas teria como fazer isso de uma forma mais generica?

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/META-INF/applicationContext.xml");
         UfBusiness ufBusiness = applicationContext.getBean(UfBusiness.class);
wagnerfrancisco

Mais genérica em que aspecto?

vasilvei

Tipo que ele fizesse para mim automático, eu uso o vraptor e ele faz isso de forma automática:

@Component
public class CriadorDeEntityManager implements ComponentFactory<EntityManager> {

	private final EntityManagerFactory factory;
	private EntityManager manager;

	public CriadorDeEntityManager(EntityManagerFactory factory) {
		this.factory = factory;
	}

	@PostConstruct
	public void abre() {
		this.manager = factory.createEntityManager();
	}

	public EntityManager getInstance() {
		return this.manager;
	}

	@PreDestroy
	public void fecha() {
		this.manager.close();
	}

queria saber se o spring tem algo parecido com isso.

wagnerfrancisco

Eu não sei como você implementou o seu repositório, mas o spring faz o controle transacional e injeta o EntityManager, se é isto que você precisa. No caso, você pode fazer este controle por anotações ou interceptar os métodos por aspectos que você define. No caso de anotações, você faria algo assim:

//...
public class UfBusiness {
   //...
   @Transactional
   public void save() {
      //...
      repository.save
   }

   @Transactional(readOnly=true) 
   public List<Uf> getAll() {
       return repository.getAll();
   }
}

A anotação @Transactional abre uma sessão se necessário e, se houver algum erro, fará rollback (você pode customizar o comportamento nos parâmetros da anotação.

Se você não quiser usar anotações, pode criar via aspectos. Aí você diz, por exemplo, “quero fazer controle transacional em todos os métodos set das classes que terminam com Service”. Algo do gênero, seria importante dar uma lida com calma na documentação, mas é possível.

No caso de usar anotações, você precisa adicionar a seguinte configuração no applicationContext.xml:

<tx:annotation-driven />
Criado 7 de agosto de 2012
Ultima resposta 7 de ago. de 2012
Respostas 7
Participantes 2