Pessoal, estou com uma dúvida quanto ao uso de transações com hibernate por exemplo:
try{
for (int t=0; t<3; t++){
User seller = new User();
seller.setUserName("xam");
seller.setName( new Name("Max", new Character('R'), "Andersen") );
seller.setEmail("max@hibernate.org");
seller.setPassword("******");
session.save(seller);
}
session.flush();
tx.commit();
session.close();
}
catch(Exception e){
tx.rollback();
session.close();
JOptionPane.showMessageDialog(null, e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
}
Suponhamos que o campo Username seja a chave primária, então na 2 iteração do loop geraria um erro na chave primária. A transação não deveria ser abortada e nenhum registro seria inserido ?
Mas nos meus testes, mesmo caindo no bloco except com tx.rollback, o primeiro registro não é excluido. Alguem pode me dar uma força? valeu
Seu BD suporta transações?
Sim, estou usando o mysql com INNODB.
Faça um simples teste com JDBC para garantir que as transaçõs funcionam.
Obrigado por responder, Daniel. É o seguinte, o mysql por default usa o AUTOCOMMIT=true, me parece que esse é o problema, áí vem a dúvida: como faço para setar o AUTOCOMMIT=false ?
Creio que o Hibernate deveria cuidar disso, não?
Pois é… esse é meu problema, estou iniciando agora com hibernate, ainda tenho muito o que aprender, mas vendo o log do hibernate ele
seta o modo autocommit como false, logo deveria funcionar, não?
10:50:33,265 INFO Environment:479 - Hibernate 3.1.3
10:50:33,281 INFO Environment:494 - loaded properties from resource hibernate.properties: {hibernate.connection.driver_class=com.mysql.jdbc.Driver, hibernate.cglib.use_reflection_optimizer=true, hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider, hibernate.max_fetch_depth=1, hibernate.dialect=org.hibernate.dialect.MySQLMyISAMDialect, hibernate.jdbc.use_streams_for_binary=true, hibernate.format_sql=true, hibernate.query.substitutions=yes 'Y', no 'N', hibernate.proxool.pool_alias=pool1, hibernate.connection.username=root, hibernate.cache.region_prefix=hibernate.test, hibernate.connection.url=jdbc:mysql://localhost/testehibernate, hibernate.connection.password=****, hibernate.jdbc.batch_versioned_data=true, hibernate.connection.pool_size=1}
10:50:33,296 INFO Environment:524 - using java.io streams to persist binary types
10:50:33,296 INFO Environment:525 - using CGLIB reflection optimizer
10:50:33,296 INFO Environment:555 - using JDK 1.4 java.sql.Timestamp handling
10:50:33,453 INFO Configuration:497 - Reading mappings from resource: org/hibernate/auction/AuctionItem.hbm.xml
10:50:33,750 INFO HbmBinder:309 - Mapping class: org.hibernate.auction.AuctionItem -> AuctionItem
10:50:33,906 INFO Configuration:497 - Reading mappings from resource: org/hibernate/auction/Bid.hbm.xml
10:50:33,953 INFO HbmBinder:309 - Mapping class: org.hibernate.auction.Bid -> Bid
10:50:34,000 INFO HbmBinder:824 - Mapping subclass: org.hibernate.auction.BuyNow -> Bid
10:50:34,015 INFO Configuration:497 - Reading mappings from resource: org/hibernate/auction/User.hbm.xml
10:50:34,046 INFO HbmBinder:309 - Mapping class: org.hibernate.auction.User -> AuctionUser
10:50:34,062 INFO HbmBinder:2349 - Mapping collection: org.hibernate.auction.AuctionItem.bids -> Bid
10:50:34,062 INFO HbmBinder:2349 - Mapping collection: org.hibernate.auction.User.bids -> Bid
10:50:34,062 INFO HbmBinder:2349 - Mapping collection: org.hibernate.auction.User.auctions -> AuctionItem
10:50:34,296 INFO DriverManagerConnectionProvider:41 - Using Hibernate built-in connection pool (not for production use!)
10:50:34,296 INFO DriverManagerConnectionProvider:42 - Hibernate connection pool size: 1
10:50:34,296 INFO DriverManagerConnectionProvider:45 - autocommit mode: false
....
Exato!
Para dirimir suas dúvidas, faça um teste com JDBC apenas.
java.sql.Statement stm = conn.createStatement();
stm.execute("begin");
stm.execute("insert into teste (codigo) values (23)");
stm.execute("rollback");
Esse código funciona corretamente, isso é, não insere nada no banco. Agora não sei como ficaria a transação com hibernate…
hehehehe…
testa assim:
Statement stm = conn.createStatement();
conn.setAutoCommit(false);
stm.execute("insert into teste (codigo) values (23)");
stm.execute("insert into teste (codigo) values (24)");
conn.rollback();
[quote=danieldestro]hehehehe…
testa assim:
Statement stm = conn.createStatement();
conn.setAutoCommit(false);
stm.execute("insert into teste (codigo) values (23)");
stm.execute("insert into teste (codigo) values (24)");
conn.rollback();[/quote]
Foi mal… dei uma viajada, mas usando conn.setAutoCommit(false) funciona, isso é, não inclui nada… Tá meio estranho isso não?
Olá adriano
para setar o autoCommit = false adicione o seguinte no seu
arquivo de configuração do Hibernate
false
Já tive um problema assim e resolveu com essa tag.
Abraço
Puxa vida, até que enfim consegui. Estava fazendo uma burrada. No meu arquivo hibernate.properties as duas linhas a seguir estava descomentadas
Então quando o hibernate criava as tabelas, estava criando no formato MyIsam (sem suporte a transação). Mas o estranho é que quando eu testei com JDBC a transação funcionou mesmo assim…
Muito obrigado a todos que me ajudaram.