Olá senhores, estou com um problema com JPA. Antigamente, usava JDBC para minhas aplicações em WEB e tinha uma pasta Config com um arquivo properties onde salvava minhas configurações do banco, para que o meu cliente toda a vez que mudasse o banco ou a senha não precisasse me contatar para fazer o mesmo. Bastava configurar o properties e reiniciar o aplicativo e pronto. Estou iniciando em JPA e surgiu a dúvida, como ficará a parte para o meu usuário? Será arquivo XML e como posso por para ele configurar esse arquivo sem que o mesmo esteja dentro do meu war ? Ou seja, quero que fique igualmente como era no meu JDBC. Creio que agora seja XML e não properties, quanto a isto não é problema. O problema é como configurar esse arquivo para que fique fora do meu war . Antes que me perguntem uso Netbeans, aguardo respostas. Obrigado.
JDBC e JPA
15 Respostas
ei Caio to com o mesmo problema mas andei
dando uma olhada e ja dei uma evoluida
os passos sao o seguinte se vc usar JPA
vai ter q criar um arquivo persistence.xml
...
<properties>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.connection.username" value="sa_fila"/>
<property name="hibernate.connection.password" value="sa_fila"/>
<property name="hibernate.connection.url" value=""/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="transaction.factory_class" value="org.hibernate.transaction.JDBCTransactionFactory"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
...
e depois em um arquivo de propriedade
pegar a propriedade e sobrescrever o
hibernate.connection.url
to tentando fazer a parte que sobrescreve.
qualquer evolução te passo.
Valeu cara por responder, mas como uso netbeans ele já gera para mim. A dúvida é como deixar mesmo fora do WAR ^^
Se eu descobrir algo te aviso.
bem se colocar fora de source, dentro de src por exemplo acho que nao vai para o war nao.
Agora uma curiosidae pq fazer isso?
Olá amigo, se deixar dentro da pasta src ele irá coloca dentro sim :X
O porque de fazer isto é que meus clientes possam querer mudar a senha deles todas as vezes sem ter que me contactar para gerar outro war. 
Se souberes como fazer isto, contribue conosco, obrigado ^^
Olá,
Sem tirar crédito de ninguém achei alguns exemplos aqui no GUJ, mas segue o código que adaptei e estou utilizando.
Na raiz do meu projeto criei uma pasta chamada config, e criei o arquivo database.properties assim:
username=usuario
password=senha
Config.java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class Config {
private static final String arqConfDB = "config/database.properties";
public static Map getConfDB(){
// o arquivo encontra-se no mesmo diretório da aplicação
File file = new File(arqConfDB);
Properties props = new Properties();
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
//lê os dados que estão no arquivo
props.load(fis);
fis.close();
}
catch (IOException ex) {
System.out.println("Erro lendo database.properties:"+ex.getMessage());
}
validaConfDB(props,"username");
validaConfDB(props,"password");
Map prop = new HashMap();
prop.put("hibernate.connection.username", props.getProperty("username"));
prop.put("hibernate.connection.password", props.getProperty("password"));
return prop;
}
private static void validaConfDB(Properties prop, String param){
if ((prop.getProperty(param) == null) || (prop.getProperty(param).isEmpty())){
throw new ExceptionInInitializerError("("+arqConfDB+")"+"Propriedade:"+param+" não informada ou sem valor.");
}
}
}
e na minha conexão com o EntityManager faço assim:
Config conf = new Config();
EntityManagerFactory emf = Persistence.createEntityManagerFactory("nomePersistentUnit",conf.getConfDB());
EntityManager em = emf.createEntityManager();
O meu é muito mais complexo, e ainda falta melhorar algumas coisas.
Espero que ajude.
[]'s
Não é melhor usar um datasource ao invés de fazer uma gambiarra?
Se você usar um datasource, basta seu cliente ir no arquivo de config do datasource ou então entrar no admin do próprio container e alterar os dados. Assim nem mesmo é preciso reiniciar a aplicação.
Mas onde eu faço a configuração direcionando o arquivo de datasource, de forma que não fique dentro do meu JAR/WAR.
E como seriam as configurações deste datasouce?
Grato.
Interessante, irei analisar depois com mais calma. Obrigado aos dois, estou procurando aqui sobre datasource no google. E sobre o que você fez amigo Cobra pensei em fazer também, meus projetos todos tem Config. Mas eu fiz foi burrice minha, era pra ter lido a documentação para poder ter visto o método que você usou passando o config
createEntityManagerFactory("nomePersistentUnit",conf.getConfDB());
Cobra.cne
fiz como tu colocou ai em cima.
blz até certo ponto
só uma duvida rapida
eu coloquei no arquivo de propriedade
hibernate.connection.url = jdbc:postgresql://10.10.2.124:5432/fila
consigo pegar e td mais blz,
mas no DAO como eu faço pra pegar essa conexao?
ja que ele ainda ta indo buscar no persistence.xml
Map configOverrides = new HashMap();
configOverrides.put("hibernate.connection.url", urlBanco);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("fila", configOverrides);
EntityManager e = emf.createEntityManager();
DAO
public class GuicheDAO {
private EntityManagerFactory factory;
private static GuicheDAO instance = new GuicheDAO();
private GuicheDAO() {
factory = Persistence.createEntityManagerFactory("fila");
}
public static GuicheDAO getInstance() {
return instance;
}
public Guiche salvar(Guiche guiche) {
EntityManager entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(guiche);
entityManager.getTransaction().commit();
entityManager.close();
return guiche;
}
batista.gerson, você terá que fazer o mesmo processo, dai depende de como você esta implementando, no meu caso eu criei uma classe com estas propriedades a serem substituídas, e sempre terei que utilizá-la para toda a situação em que efetuar a conexão.
Você poderia implementar em todos DAOs esta configuração que irá substituir as informações, porém em caso de alguma mudança ou incremento de outras propriedades seria necessário alterar todos.
private GuicheDAO() {
Map configOverrides = new HashMap();
configOverrides.put("hibernate.connection.url", urlBanco);
factory = Persistence.createEntityManagerFactory("fila",configOverrides);
}
Assim sugiro que crie uma outra classe especializada em lhe retornar o “configOverrides”, e utilize em todos os DAOs, assim se precisar alterar/incluir/remover alguma propriedade irá efetuar somente nesta classe, parecido com o meu exemplo.
private GuicheDAO() {
SuaClasseConfig configOverrides = new SuaClasseConfig();
factory = Persistence.createEntityManagerFactory("fila",configOverrides);
}
Espero que tenha entendido.
[]'s
Cobra.cne
valeu cara
fiz como você sugeriu
e funcionou perfeitamente
por enquanto, pois ainda estou fazendo
testes, mas acho que isso resolver perfeitamente!
Datasource você configura no servidor de aplicação, e não na aplicação. Por isso eu te sugeri isso, pois assim o próprio container fica responsável pela conexão. Na aplicação fica apenas a indicação do nome do datasource. Os dados de conexão e acesso ficam dentro do servidor de aplicação. Assim você pode alterar o datasource sem precisar alterar nada na aplicação nem mesmo fazer restart.
Segue o inicio do meu persistence.xml
<persistence-unit name="defaultPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/pgsqlDS</jta-data-source>
A configuração do datasource depende do servidor, e isso você pode facilmente achar. Qual o servidor que você usa? Se precisar posso te ajudar.
Como o garcia-jj falou o data source é configurado no seu container, se estiver trabalhando com o jboss você configura um xml com um sufixo ds dentro da pasta deploy…
CaioO
se você tiver usando uma aplicação web
o que o garcia-jj sugeriu funciona perfeitamente,
testei aqui e td normal
se for desktop que é o meu caso
o que o Cobra.cne sugeriu tbm
funciona perfeitamente
tanto que eu estou usando depois dos
posts que ele colocou.
Opa, desculpem é que surgiu outros programas para serem vistos. Estou usando GlassFish e também usarei o JPA para desktop. Como posso prosseguir? Agradeço e desculpem a demora na resposta.
Abaixo meu persistence.xml :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="RagCPPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>RagCPJNDI</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
Como proceder se for uma aplicação web usando glassfish e como proceder “corretamente” se for desktop. Ahh antes que eu me esqueça seria bom explicar também como seria no TomCat e no JBoss, assim esse tópico estaria com todas as coisas para que não fique repetindo outros perguntando como seria em outros servidores. ^^ Agradeço mais uma vez.