web-dev-qa-db-ja.com

hibernateでネイティブSQLを実行する

hibernate 4.2.6PostgreSQL 9.1を使用しています。HibernateでSQLクエリを実行しようとしています。私は書きました:

Session session = Hibernate.util.HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
String sql = String.format("INSERT INTO products (name,cost) VALUES('%s',%s);", product.getName(), product.getCost());
createSQLQuery(sql);//has no effect. Query doesn't execute.
session.getTransaction().commit();
session.close();

このクエリはDBでは実行されません。しかし、私が書いた場合

String sql = String.format("INSERT INTO products (name,cost) VALUES('%s',%s);", product.getName(), product.getCost());
Properties connectionProps = new Properties();
connectionProps.put("user", "postgres");
connectionProps.put("password", "123");
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/solid",connectionProps);
conn.createStatement().execute(sql);

対応する行がテーブルに追加されます。 hibernateが機能しないのに、JDBCを使用したネイティブクエリが機能するのはなぜですか?

7
St.Antario

これはあなたを助けるはずです。

Session session = Hibernate.util.HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
String sql = String.format("INSERT INTO products (name,cost) VALUES('%s',%s);",product.getName(), product.getCost());
session.createSQLQuery(sql).executeUpdate();
session.getTransaction().commit();
session.close();
13
Darshan Lila

PreparedStatement (SQLインジェクションに道を譲りたくありません)を使用することは常に良い方法です。

String sql = "INSERT INTO products (name,cost) VALUES (?,?)";

Session sess = Hibernate.util.HibernateUtil.getSessionFactory().openSession();
Connection con = sess.connection();
PreparedStatement pstmt = con.prepareStatement(sql);

pstmt.setString(1, product.getName());
pstmt.setInt(2, product.getCost());

pstmt.executeUpdate();

con.commit();
pstmt.close();
8
Jp Vinjamoori

あなたに影響を与える可能性のあるもう1つの問題(私に影響を与えるような)は次のとおりです。

ネイティブクエリを実行したいのですが、本番用コードで機能させることができませんか?スキーマの所有者とは異なるデータベースユーザーをアプリケーションに使用している場合は注意してください。その場合、スキーマプレフィックスを参照テーブルに追加して、機能させる必要があります。

私の例では、セッションの代わりにエンティティマネージャーを使用しています。

String sql = "select id from some_table";
Query query = em.createNativeQuery(sql);
List<Long> results = query.getResultList();

some_tableが所有している場合アプリケーションがユーザーとして実行されている間は、クエリを次のように変更する必要があります。

String sql = "select id from dba.some_table";

Hibernateですべてのテーブルにプレフィックスを付けるように設定する

<prop key="hibernate.default_schema">dba</prop>

どうやらネイティブクエリには影響しません。

5
BrotherBear

私のために働く解決策は次のとおりです:

public List<T> queryNativeExecute(String query) throws CustomException {
        List<T> result =null;
        Session session =null;
        Transaction transaction=null; 
        try{
            session = HibernateUtil.getSessionJavaConfigFactory().openSession();
            transaction = session.beginTransaction();
            session.createNativeQuery(query).executeUpdate();
            transaction.commit();
        }catch(Exception exception){
            result=null;
            if (transaction !=null && transaction.isActive()){
                transaction.rollback();
            }
            throw new CustomException(exception.getMessage(),exception,error.ErrorCode.DATABASE_TABLE,this.getClass().getSimpleName());
        }finally{
            if (session !=null){
                session.close();    
            }
        }

        return result;
    }   
1