Então, (atendendo a pedidos :lol: ) continuando o exemplo (JUnit no topo do Business-Core): Aki está o ‘persistence.xml’:<persistence ... >
<persistence-unit name="agendaJPA2-corePU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--non-jta-data-source>java:/comp/env/jdbc/agendaDS</non-jta-data-source-->
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/agenda"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
</properties>
</persistence-unit>
<persistence-unit name="agendaJPAds-corePU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--validation-mode>NONE</validation-mode-->
<jta-data-source>jdbc/agendaDS</jta-data-source>
<properties/>
</persistence-unit>
</persistence>
(Obs.: substitua todos “agenda” pelo nome da sua Base de Dados.) Agora o ‘appTestContext.xml’ (deve ser adicionado o’.LocalEntityManagerFactoryBean’ postado anteriormente): [code]<beans xmlns=… >
<!-- JPA LocalEntityManagerFactoryBean (Se “persistenceUnitName” não é definido e só há 1 PU no persistence.xml, ela(ou a 1ª PU) é usada. -->
…
<!-- Transaction manager para um JPA EntityManagerFactory simples (alternativa ao JTA) -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- Instrui o Spring a realizar gerenciamento transacional declarativo automático nas classes anotadas.–>
<tx:annotation-driven/>
<!-- PostProcessors para realizar injeção de recursos de acordo com a especificação JPA (@PersistenceContext, @PersistenceUnit). -->
<!-- Arquivo onde todos os Objetos (instanciados) declarados como <bean . -->
<import resource="appObjetos.xml" />
</beans>[/code]
O ‘applicationContext.xml’ p/ ser usado p/ Aplicação em Produção (inclusive se vc deseja configurar o Transacional explicitamente no Spring usando a abordaem da JTA API): [code]<beans xmlns=… >
<!-- JNDI Lookup via JndiTemplate: esta setting permite lookUp da DataSource reBindada no UnitTest.–>
<bean id=“jndiTemplate” class=“org.springframework.jndi.JndiTemplate”>
<property name=“environment”>
<props>
<prop key=“java.naming.factory.initial”>com.sun.jndi.fscontext.RefFSContextFactory</prop>
<prop key=“java.naming.provider.url”>file:/</prop>
</props>
</property>
</bean>
<!-- Datasource de JNDI Lookup(via “jndiTemplate”) <- esta setting p/ ser usada em Produção: DataSource de Container Java.–>
<bean id=“jndiDataSource” class=“org.springframework.jndi.JndiObjectFactoryBean”>
<property name=“jndiTemplate”>
<ref bean=“jndiTemplate”/>
</property>
<property name=“jndiName”>
<value>java:/comp/env/jdbc/agendaDS</value>
</property>
</bean>
<!-- EntityManagerFactory <- DataSource de Container Java(Se há + de 1 PU no persistence.xml, o nome da PU deve ser determinado em persistenceUnitName).–>
<bean id=“entityManagerFactory” class=“org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean”>
<!-- esta setting p/ ser usada em Produção: DataSource de Container Java.–>
<property name=“dataSource” ref=“jndiDataSource”></property>
<property name=“persistenceUnitName” value=“agendaJPAds-jarPU” />
<property name=“jpaPropertyMap”>
<map>
<entry key=“hibernate.transaction.manager_lookup_class” value=“org.hibernate.transaction.JBossTransactionManagerLookup”/>
<entry key=“hibernate.transaction.flush_before_completion” value=“true”/>
<entry key=“hibernate.transaction.auto_close_session” value=“true”/>
<entry key=“hibernate.current_session_context_class” value=“jta”/>
<entry key=“hibernate.connection.release_mode” value=“auto”/>
</map>
</property>
<!-- custom implementation p/ enriquecer o PersistenceUnitInfo read from the persistence.xml
JPA configuration file with the JTA DataSource, specifying the JTA datasource directly in
the Spring configuration file has the advantage that we can use a direct reference to the
datasource instead of using a JNDI name as requied by the jta-data-source setting in the
persistence.xml file -->
<property name=“persistenceUnitPostProcessors”>
<list>
<!-- Obs.: a Classe deste Objeto, “JtaPersistenceUnitPostProcessor”, deve ser definida na App.–>
<bean class=“JtaPersistenceUnitPostProcessor”>
<property name=“jtaMode” value=“true”></property>
<property name=“jtaDataSource” ref=“jndiDataSource”></property>
</bean>
</list>
</property>
<!-- customização do JPA Provider (neste caso o Hibernate). -->
<property name=“jpaVendorAdapter”>
<bean class=“org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter”>
<property name=“showSql” value=“true” />
<property name=“generateDdl” value=“false” />
<!–property name=“database” value=“MYSQL” /–>
<property name=“databasePlatform” value=“org.hibernate.dialect.MySQL5Dialect” />
</bean>
</property>
</bean>
<!-- JTA Transaction Manager este setting p/ ser usada em Produção: Container Java.–>
<bean id=“transactionManager” class=“org.springframework.transaction.jta.JtaTransactionManager”>
<property name=“transactionManagerName” value=“java:/TransactionManager”></property>
<property name=“autodetectUserTransaction” value=“false”></property>
</bean>
<!-- Instrui o Spring a realizar gerenciamento transacional declarativo automático nas classes anotadas.–>
<tx:annotation-driven/>
<!-- PostProcessors para realizar injeção de recursos de acordo com a especificação JPA (@PersistenceContext, @PersistenceUnit). -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<!-- PostProcessors para realizar a conversão de exceções nas classes @Repository (das exceções nativas como JPA PersistenceExceptions to Spring's DataAccessException). -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- Será automaticamente transacional graças ao @Transactional. EntityManager irá ser auto-injetado graças ao @PersistenceContext. PersistenceExceptions irá ser auto-convertido graças ao @Repository. -->
<!-- Arquivo onde todos os Objetos (instanciados) declarados como <bean . -->
<import resource="appObjetos.xml" />
</beans>[/code]Obs.: a implementação da Classe “JtaPersistenceUnitPostProcessor”, pode ser obtida no link fornecido anteriormente.
Agora o “appObjetos.xml” (usado por ambos 'app*Context.xml’s):[code]<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=“http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd”>
<!-- O Spring é 1 Container FrameWork, portanto, se configurado via XML, todos os Objetos (instanciados) tem q ser definidos como <bean . -->
<!-- a não ser que esteja configurado com (Injeção de Dependecia via) Annotation Component-Scan. -->
<context:annotation-config/>
<context:component-scan base-package="domain.srvcFacade,domain.repository" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
<!--context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/-->
</context:component-scan>
<bean id="usuario" class="domain.model.Usuario" scope="session" />
<!--bean id="usuarioRepo" class="domain.repository.UsuarioRepo" />
<bean id="usuarioServiceFcd" class="domain.srvcFacade.UsuarioServiceFcd">
<property name="usuarioRepo" ref="usuarioRepo" />
</bean-->
<bean ... >
</beans>[/code]Eventualmente 1 DAO seguindo o padrão: [code]
package domain.repository;
@Transactional
//@Scope(“prototype”) // esta @ somente no caso DI via Annotations
@Repository
public class UsuarioRepo {
@PersistenceContext
private EntityManager em;
// demais codificações de Persistencia/Acesso a Dados…
}[/code]O ‘Domain Service’: [code]package domain.srvcFacade;
@Service
public class UsuarioServiceFcd {
@Autowired // esta @ somente no caso DI via Annotations (context:component-scan)
private UsuarioRepo usuarioRepo;
/** demais codificações de Serviço de Domínio... */
}[/code]E finalmente o Caso de Teste ‘UsuarioServiceFcdTest.java’: voi la[code]public class UsuarioServiceFcdTest {
private ApplicationContext context;
UsuarioServiceFcd usuarioServiceFcd;
/…/
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
System.setProperty(Context.PROVIDER_URL, "file:/"); // change provider url to a platform specific path
Context registry = new InitialDirContext();
// create a new connection pool data source, read the properties
// file
// and bind it to a name
ComboPooledDataSource cpds = new ComboPooledDataSource();
Properties dsProperties = new Properties();
FileInputStream cpdsPropFile = new FileInputStream("C:/…pathDirSeuProjeto…/test/jdbc.properties");// myconnection.properties created in step1
dsProperties.load(cpdsPropFile);
try {
cpds.setDriverClass(dsProperties.getProperty("driverClass"));
} catch (PropertyVetoException ex) {
Logger.getLogger(UsuarioServiceFcdTest.class.getName()).log(Level.SEVERE, null, ex);
}
cpds.setUser(dsProperties.getProperty("user"));
cpds.setDescription("java:/comp/env/jdbc/agendaDS" + " Data Source"); //replace MYCONNECTIONKEY with the key you wish to use for lookup
cpds.setPassword(dsProperties.getProperty("password"));
cpds.setJdbcUrl(dsProperties.getProperty("jdbcUrl"));
cpds.setIdleConnectionTestPeriod(1800);
cpds.setMaxIdleTime(3000);
cpds.setMaxStatements(50);
cpds.setMaxPoolSize(5);
cpds.setInitialPoolSize(3);
cpds.setAcquireIncrement(5);
cpds.setMinPoolSize(2);
cpds.setTestConnectionOnCheckin(true);
Connection conC3PO = cpds.getConnection();
if (conC3PO != null){
System.out.println(" Success ; ;"); //Success
// ...
registry.rebind("java:/comp/env/jdbc/agendaDS", cpds); //datasource
// "closing" a connection sends it back to the pool
conC3PO.close();
} else {
//Something wrong
}
InitialContext ic = new InitialContext();
// ic.createSubcontext("java:");
// ic.createSubcontext("java:/comp");
// ic.createSubcontext("java:/comp/env");
// ic.createSubcontext("java:/comp/env/jdbc");
// Construct DataSource = /* …*/
// ic.bind("jdbc/agendaDS", datasource);
// Context webContext = (Context)ic.lookup("java:/comp/env");
DataSource datasource2 = (DataSource)ic.lookup("java:/comp/env/jdbc/agendaDS"); //DataSource datasource2 = (DataSource)webContext.lookup("jdbc/agendaDS")
//
try {
System.out.println("DB Schema/Catalog is " + datasource2.getConnection().getCatalog().toString() ); //*StartedUp JNDI.
Connection con = datasource2.getConnection(); // ds.getConnection("genius", "abracadabra")
System.out.println("Ds Context name is " + con.getCatalog().toString() );//datasource2.getConnection() *StartedUp JNDI.datasource2.getConnection().
//con.setAutoCommit(false);
//PreparedStatement pstmt = (PreparedStatement)con.prepareStatement( //
// "SELECT * FROM usuario"); // NAME, NAME, TITLE TITLEPERSONNEL WHERE DEPT = ?
////pstmt.setString(1, "SALES");
//ResultSet rs = pstmt.executeQuery();
String sQry = "SELECT * FROM usuario"; //any sQry
Statement stmt = (Statement)con.prepareStatement(sQry);
ResultSet rs = stmt.executeQuery(sQry); // sQry
System.out.println("(testando) Buscando dados..."); // Sales Department:
while (rs.next() ) {
String name = rs.getString("NoME");
String title = rs.getString("login");
System.out.println(name + " ; ;" + title);
}
rs.close();
stmt.close();
con.close();
} catch (SQLException ex) {
Logger.getLogger(UsuarioServiceFcdTest.class.getName() ).log(Level.SEVERE, null, ex);
throw new SQLException("SQLException: " + ex.getMessage() );
}
// System.out.println("JNDI Context name is " + JNDIUnitTestHelper.getJndiName() );//*StartedUp JNDI.
context = new ClassPathXmlApplicationContext("appTestContext.xml"); // applicationContext // *2 <- pode alternar quando estiver c/ o ambiente funcionando.
usuarioServiceFcd = (UsuarioServiceFcd)context.getBean("usuarioServiceFcd");
/…/
@Test
public void gravar() {
System.out.println("gravar usuário");
Usuario result = usuarioServiceFcd.gravar(usuarioTeste);
try {
assertNotNull(result.getIdUsuario() );
} catch (AssertionError e){
fail("Falhou a gravação de usuário! Falha: " + e.getMessage() );
}
}
[/code]*2 :idea:<- ah e, a propósito, use a ferramenta de geração de JUnit Test’s do netBeans e implemente seus testes a gosto (claro, sempre implemente os Testes Unitários antes de implementar qq funcionalidade)TDD!!! :XD:
(Vc ficou me devendo a versão do seu netBeans. Aproveita e me passa a do Hibernate (presumo 3.5+) e o seu Spring (q parece ser a 3.x+: pq tentou usar @Resource).)
Clareou 1 pouco?!!