Wir müssen in der Lage sein, die zugehörige java.sql.Connection
Sitzung im Ruhezustand abzurufen. Es funktioniert keine andere Verbindung, da diese Verbindung möglicherweise einer laufenden Transaktion zugeordnet ist.
Wie soll ich das tun, wenn session.connection () jetzt veraltet ist?
Antworten:
Sie müssen jetzt die Arbeits-API verwenden:
session.doWork( new Work() { public void execute(Connection connection) throws SQLException { doSomething(connection); } } );
Oder in Java 8+:
quelle
SessionImpl sessionImpl = (SessionImpl) session; Connection conn = sessionImpl.connection();
Sie können das Verbindungsobjekt dann überall dort verwenden, wo Sie es in diesem Code benötigen, und nicht nur auf eine kleine Methode beschränken.session.doWork(this::doSomething)
. Wenn Sie ein Ergebnis zurückgeben möchten, verwenden Sie doReturningWork ()Sie müssen
Session#doWork(Work)
und dieWork
API verwenden, wie im Javadoc erwähnt:Sie haben einige Zeit vor Hibernate 4.x, aber die Verwendung einer veralteten API sieht irgendwie so aus:
:) :)
Update: Laut RE: [hibernate-dev] Verbindungs-Proxy auf der Hibernate-dev-Liste scheint es, dass die ursprüngliche Absicht der Ablehnung darin bestand, die Verwendung von zu verhindern,
Session#connection()
da es als "schlechte" API angesehen wurde / wird, aber es sollte zu dieser Zeit bleiben. Ich denke, sie haben ihre Meinung geändert ...quelle
Session#connection()
in Hibernate Core 3.3 erwähnt die Alternative) und das können Leser normalerweise nicht erraten.hibernate
) verwenden und nichthibernate-core
das, das neuere Versionen hat. Und für ultimative Versionen (3.5.x) sind sie im JBoss Nexus-Repository verfügbar .Versuche dies
Tatsächlich gibt getSession den Typ der Sitzungsschnittstelle zurück. Sie sollten sehen, was die ursprüngliche Klasse für die Sitzung ist. Geben Sie cast in die ursprüngliche Klasse ein und erhalten Sie die Verbindung.
VIEL GLÜCK!
quelle
SessionImpl
befindet sich in einem internen Paket von Hibernate (daher nicht zur Verwendung vorgesehen) und dies ist auch eine Abhängigkeit von der tatsächlichen Implementierung. Außerdem können Sie die Sitzung in Ihren Tests nicht einfach verspotten, wenn Sie sie wirken.Es gibt noch eine andere Option, an der immer noch viele Casts beteiligt sind, aber zumindest muss sie nicht reflektiert werden, wodurch Sie die Überprüfung der Kompilierungszeit zurückerhalten können:
public Connection getConnection(final EntityManager em) { HibernateEntityManager hem = (HibernateEntityManager) em; SessionImplementor sim = (SessionImplementor) hem.getSession(); return sim.connection(); }
Sie könnten das natürlich mit ein paar
instanceof
Überprüfungen noch "schöner" machen , aber die obige Version funktioniert für mich.quelle
Hier ist eine Möglichkeit, dies in Hibernate 4.3 zu tun, und es ist nicht veraltet:
quelle
session
zuSessionImplementor
?Das benutze ich und arbeite für mich. Downcast das Session-Objekt in ein SessionImpl und erhalte das Verbindungsobjekt einfach:
Wo
session
ist der Name Ihres Sitzungsobjekts im Ruhezustand?quelle
connection()
wurde nur auf der Schnittstelle veraltet. Es ist noch verfügbar amSessionImpl
. Sie können das tun, was der Frühling tut, und das einfach so nennen.Hier ist der Code aus dem
HibernateJpaDialect
Frühjahr 3.1.1public Connection getConnection() { try { if (connectionMethod == null) { // reflective lookup to bridge between Hibernate 3.x and 4.x connectionMethod = this.session.getClass().getMethod("connection"); } return (Connection) ReflectionUtils.invokeMethod(connectionMethod, this.session); } catch (NoSuchMethodException ex) { throw new IllegalStateException("Cannot find connection() method on Hibernate session", ex); } }
quelle
Ich habe diesen Artikel gefunden
package com.varasofttech.client; import java.sql.Connection; import java.sql.SQLException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.SessionImpl; import org.hibernate.jdbc.ReturningWork; import org.hibernate.jdbc.Work; import com.varasofttech.util.HibernateUtil; public class Application { public static void main(String[] args) { // Different ways to get the Connection object using Session SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); // Way1 - using doWork method session.doWork(new Work() { @Override public void execute(Connection connection) throws SQLException { // do your work using connection } }); // Way2 - using doReturningWork method Connection connection = session.doReturningWork(new ReturningWork<Connection>() { @Override public Connection execute(Connection conn) throws SQLException { return conn; } }); // Way3 - using Session Impl SessionImpl sessionImpl = (SessionImpl) session; connection = sessionImpl.connection(); // do your work using connection // Way4 - using connection provider SessionFactoryImplementor sessionFactoryImplementation = (SessionFactoryImplementor) session.getSessionFactory(); ConnectionProvider connectionProvider = sessionFactoryImplementation.getConnectionProvider(); try { connection = connectionProvider.getConnection(); // do your work using connection } catch (SQLException e) { e.printStackTrace(); } } }
Es hat mir geholfen.
quelle
Mit
Hibernate
> = 5.0 erhalten Sie FolgendesConnection
:quelle
Versuchen Sie für Hibenat 4.3 Folgendes:
public static Connection getConnection() { EntityManager em = <code to create em>; Session ses = (Session) em.getDelegate(); SessionFactoryImpl sessionFactory = (SessionFactoryImpl) ses.getSessionFactory(); try{ connection = sessionFactory.getConnectionProvider().getConnection(); }catch(SQLException e){ ErrorMsgDialog.getInstance().setException(e); } return connection; }
quelle
Versuche dies:
public Connection getJavaSqlConnectionFromHibernateSession() { Session session = this.getSession(); SessionFactoryImplementor sessionFactoryImplementor = null; ConnectionProvider connectionProvider = null; java.sql.Connection connection = null; try { sessionFactoryImplementor = (SessionFactoryImplementor) session.getSessionFactory(); connectionProvider = (ConnectionProvider) sessionFactoryImplementor.getConnectionProvider().getConnection(); connection = connectionProvider.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return connection; }
quelle
Connection conn = null; PreparedStatement preparedStatement = null; try { Session session = (org.hibernate.Session) em.getDelegate(); SessionFactoryImplementor sfi = (SessionFactoryImplementor) session.getSessionFactory(); ConnectionProvider cp = sfi.getConnectionProvider(); conn = cp.getConnection(); preparedStatement = conn.prepareStatement("Select id, name from Custumer"); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { System.out.print(rs.getInt(1)); System.out.println(rs.getString(2)); } } catch (Exception e) { e.printStackTrace(); } finally { if (preparedStatement != null) { preparedStatement.close(); } if (conn != null) { conn.close(); } }
quelle
Hier ist eine Java 8-Methode, um die
Connection
von einem verwendeten zurückzugeben,EntityManager
ohne tatsächlich etwas damit zu tun:private Connection getConnection(EntityManager em) throws SQLException { AtomicReference<Connection> atomicReference = new AtomicReference<Connection>(); final Session session = em.unwrap(Session.class); session.doWork(connection -> atomicReference.set(connection)); return atomicReference.get(); }
quelle