2015-02-18 6 views
0

Я использую JPA в одном проекте с Hibernate, и я имел необходимость выполнять некоторые операции на чистый JDBC уровне, так что я использовал этот метод, чтобы получить подключение к моей базе данных:Hibernate возвращает «странное» соединение

public class ConnectionUtil { 
    public static EntityManagerFactory EMF = Persistence 
     .createEntityManagerFactory("persistenceUnitName"); 

    public static Connection getConnection() throws SQLException { 

     Connection connection = null; 
     EntityManager em = null; 
     try { 
      em = EMF.createEntityManager(); 
      Session session = (Session)EMF.createEntityManager() 
        .getDelegate(); 
      SessionFactoryImplementor sfi = (SessionFactoryImplementor) session 
        .getSessionFactory(); 
      @SuppressWarnings("deprecation") 
      ConnectionProvider cp = sfi.getConnectionProvider(); 
      connection = cp.getConnection(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (em != null) { 
       em.close(); 
      } 
     } 

     return connection; 
    } 
} 

И я использовал этот метод для вставки записей в моей базе данных:

public void saveOrUpdate(String sqlStatement, Connection connection, Object... args) { 
     Connection connection = null; 
     PreparedStatement preparedStatement = null; 

     try { 

      preparedStatement = connection.prepareStatement(sqlStatement); 
      for (int i = 0; i < args.length; i++) { 
       preparedStatement.setObject(i + 1, args[i]); 
      } 
      preparedStatement.execute(); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       if (connection != null) { 
        connection.close(); 
       } 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      try { 
       if (preparedStatement != null) { 
        preparedStatement.close(); 
       } 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
     } 

    } 

Реализация выглядит следующим образом:

saveOrUpdate("INSERT INTO my_table(my_column) VALUES (?)", ConnectionUtil.getConnection(), "MyValue"); 

Ничего особенного. Кроме того, это не сработает. Никаких исключений, ничего. Но запись не вставлена. Отбор работает по назначению. Он возвращает записи. Затем я поменял местами соединения. Я создал соединение в классическом способе:

Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/db","u","p"); 

прошла c вместо ConnectionUtil.getConnection(), и она работала.

Однако, логический вопрос, который следует этой ситуации:

Если я не могу вставить запись, используя соединение, возвращенное getConnection метода, то как можно Hibernate вставить запись, если он использует ту же связь?

+0

Вы закрываете соединение, которое не открывали, и никогда ничего не совершаете, так что меня это не удивляет. –

+0

@JBNizet Можете ли вы уточнить? –

+0

Если я правильно понимаю, вы используете то же соединение, что и EM. Поэтому я не думаю, что вы должны закрыть эту связь. Менеджер объекта закроет его. И все, что вы делаете с EntityManager, должно выполняться внутри транзакции, которую вы фиксируете в конце. –

ответ

1

The ConnectionProvider не предназначен для использования приложением, проверьте documentation

интерфейс который ConnectionProvider не предназначен подвергаться воздействию приложения. Вместо этого он используется внутри Hibernate для получения соединений.

Итак, лучший вариант - это ваш второй подход, чтобы получить соединение классическим способом.