Hibernate Entity manager-auto-flush, bevor Abfragen und änderungen der DB in der Transaktion
Ich bin mit Hibernate 3.6.0 mit JPA 2 auf Jboss AS 6.0.0 final.
In einem EJB-von mir gibt es eine Methode, die aktualisiert entity-Werte und einige der Abfrage auf. Die ganze Methode läuft in einem BMT-Transaktion. Wenn alles andere fehlschlägt, sollten alle änderungen sein, rollback und nicht verpflichtet, DB.
Die Datenbank ist mySql.
Vor der Ausführung von JPA query, JPA automatisch Spülen Sie die geänderten Zustände der DB zu verhindern, dass irgendwelche veralteten Daten wieder aus. Aber in meiner Methode, die auto-flush direkt update und commit die änderungen an der DB und auch etwas schief, danach werden die änderungen nicht rollback. So möchte ich Fragen, ob es eine falsche Konfiguration in meinem set up oder das ein bug ist oder so etwas.
EJB
@Stateless(mappedName = "MyManagementBean")
@Local
@TransactionManagement(TransactionManagementType.BEAN)
public class MyManagement implements MyManagementLocal,MyManagementRemote {
@PersistenceUnit(unitName="MyEjb") EntityManagerFactory emf;
@Resource UserTransaction utx;
@Resource SessionContext ctx;
/**
* Default constructor.
*/
public MyManagement () {
//TODO Auto-generated constructor stub
}
public void dosomething(String id) throws Exception
{
try {
utx.begin();
em = emf.createEntityManager();
Myline line = em.find(Myline.class, id);
line.setStatus("R");
Stromg q += " from Myline as line ";
//auto flush apply here and directly committed to DB...
Iterator iter = em.createQuery(q).getResultList().iterator();
em.flush();
utx.commit();//changes should only commit after this
}
catch (Exception e) {
e.printStackTrace();
if (utx != null) utx.rollback();
throw e; //or display error message
}
finally {
em.close();
}
}
}
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="MyEjb" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:MyDS</jta-data-source>
<class>com.quincy.entity.MyLine</class>
<properties>
<property name="hibernate.connection.defaultNChar" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLMyISAMDialect"/>
<property name="hibernate.ejb.cfgfile" value="META-INF/hibernate.cfg.xml"/>
</properties>
</persistence-unit>
</persistence>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hibernate.max_fetch_depth">3</property>
</session-factory>
</hibernate-configuration>
mysql-ds.xml
<datasources>
<local-tx-datasource>
<jndi-name>MyDS</jndi-name>
<connection-url>jdbc:mysql://10.10.150.57:3306/myds</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>user</user-name>
<password>pwd</password>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
Bei weiterer Untersuchung fand ich heraus, dass, wenn es jemals einen flush, die schmutzig änderungen geschrieben und engagiert für die DB direkt. Wenn ich entfernen Sie die flush () funktioniert alles einwandfrei. Es gibt jedoch ausgelöste system Spülen, bevor die Abfrage und ich denke, es ist notwendig.
Scheint es mir, dass die db wird automatisch commited. Ich habe versucht, legen Sie die Eigenschaft hibernate.connection.autocommit
zu false
aber eben das problem fortbestehen, und ein EJB-Warnung Verletzung spec aufgefordert.
UPDATE: Die Ursache sollte kommen aus mysql. Als ob ich wechseln zu mssql-server, das problem geht Weg.Ich habe auch versucht, mysql mit xa-datasource
noch kein Glück...
P: Danke für die Antwort. Ich habe aktualisiert und enthält die jdbc-Einstellung auch. Mysql-version ist 5.0, und ich bin mit mysql-connector-java-5.1.13
InformationsquelleAutor Quincy | 2011-06-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Problem gelöst.
Die Ursache ist, dass die Tabellen in der mysql ist mit
MyISAM
engine standardmäßig und Tabellen mit diesem Motor keine Transaktionen unterstützt.Switching-Tabellen zu
innoDB
machen, was funktioniert.Hoffe, dies wäre nützlich für jeden, so dass Sie nicht verschwenden Sie so viel Zeit wie ich es Tat. 🙁
InformationsquelleAutor Quincy
Was eingestellt ist, da der entityManager FlushModeType
Die Methode nimmt einen enum definiert.
Versuchen auch die überprüfung der folgenden
nachdem Sie deklarieren die Entity manager factory.
Wenn ich den flush-Modus zu VERPFLICHTEN, den flush nicht passieren würde. Allerdings, die Abfrage liefert veraltete Daten. Das problem jetzt ist die Spülung zu Begehen, änderungen an DB direkt. Es soll ja nur Spülen Sie die änderungen an DB, aber nicht verpflichten.
Können nicht Sie die Abfrage ausführen (mit den Daten synchron), dann machen die änderung der bestimmten Zeile und dann verpflichten?
Nein. Während der Abfrage-Prozess, es ist eine Art Prüfung und möglicherweise Fehler. Ich möchte die änderungen ein rollback in diesem Fall. In meinem Verständnis, auch flush-Modus auf AUTO eingestellt ist, die änderungen würden nur gespült werden, um sichtbar für andere Abfragen, aber nicht direkt engagiert sich für die DB. Also ich Frage mich, ob ich getan hatte, alles, was falsch mit meiner config. (Dies ist mein erstes mal, um die Verwendung der JPA-API, ich war mit native hibernate vor)
Bei weiterer Untersuchung fand ich heraus, dass, wenn es jemals einen flush, die schmutzig änderungen geschrieben und engagiert für die DB direkt. Es scheint, dass die em nicht wirklich die Bindung an eine Transaktion. Aber ich kann immer noch nicht arbeiten, es out. :/
InformationsquelleAutor Luke