Hibernate vs JDBC. Производительность.
От: unkis  
Дата: 07.06.07 10:19
Оценка:
Привет всем, у меня такая проблема, я заметил что при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC.
Вот я и подумал может, я не правильно использую Hibernate.

Я написал пример, который кладёт в три таблицы 100,1000 объектов(делает 300,3000 insert) и вот результаты:
структура таблиц:
Timestamp<------->time_request<------>Request

Тестовая конфиг.
JDK 1.6
HSQL
Vindows Vista

100 объектов
Hiberane 631ms
JDBC 7ms

1000 объектов
Hiberane 5425ms
JDBC 56ms

Как видите сами, Hibernate во много раз медленнее.

Вопрос можно ли под шаманить и добиться, более приемлемых результатов у hibernate.

Тестовый проект(размер ~6Mb) можно скачать <span class='lineQuote level3'>&gt;&gt;&gt;здесь&lt;&lt;&lt;</span>, он содержит в себе всё необходимое,
только запустить и всё.
Запуск BD и GUI к ней же, осуществляется через два *.bat файла лежащих в папке lib.

Вот так я сохраняю.

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.hibernate.ejb.EntityManagerFactoryImpl;
import test.Request;
import test.RequestTime;
import test.TimeStamp;
public class MainTest {
    private EntityManagerFactory emf;
    private Session entityManager;
    private Transaction tx2;
    private int insert = 1000;
    public MainTest() {
        emf = Persistence.createEntityManagerFactory("test");
        entityManager = (Session) emf.createEntityManager().getDelegate();
        tx2 = entityManager.getTransaction();
        start();
//        saveWithNativeSQL();
    }
    private void start() {
        tx2.begin();
        ArrayList<RequestTime> liste = new ArrayList<RequestTime>();
        for (int i = 0; i < insert; i++) {
            TimeStamp timeStamp = new TimeStamp();
            timeStamp.setDay((byte) (6 + i));
            timeStamp.setHour((byte) (5 + i));
            timeStamp.setMonth((byte) (7 - i));
            Request request = new Request("XMLCON", "198.56.3.255", "wap");
            RequestTime newLink = new RequestTime(666, timeStamp, request);
            liste.add(newLink);
            //        List<RequestTime> criteria = entityManager.createCriteria(RequestTime.class).
            //        add( Restrictions.eq("request", request)).
            //        add(Restrictions.eq("timeStamp", timeStamp)).list();
        }
        long start = System.currentTimeMillis();
        for (RequestTime time : liste) {
            entityManager.save(time);
        }
        tx2.commit();
        entityManager.close();
        System.out.println("Done.\tExecuted time: "
                + (System.currentTimeMillis() - start));
    }
    private void saveWithNativeSQL() {
        try {
            Class.forName("org.hsqldb.jdbcDriver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            int[] updateCounts = null;
            java.sql.Connection con = DriverManager.getConnection(
                    "jdbc:hsqldb:hsql://localhost/test", "sa","");
            con.setAutoCommit(false);
            long start = System.currentTimeMillis();
            Statement s = con.createStatement();
            for (int i = 1; i < insert; i++) {
                s.addBatch("INSERT INTO Request VALUES (" + i
                        + ",'aaa','aaa','aaa')");
                s.addBatch("INSERT INTO TimeStamp VALUES (" + i + ",5,1,1,1)");
                s.addBatch("INSERT INTO time_request VALUES (" + i + ",5," + i
                        + "," + i + ")");
            }
            updateCounts = s.executeBatch();
            con.commit();
            System.out.println("Done.\tExecuted time: "
                    + (System.currentTimeMillis() - start));
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        new MainTest();
    }
}



<persistence 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_1_0.xsd"
    version="1.0">
    <persistence-unit name="test">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>test.TimeStamp</class>
        <class>test.RequestTime</class>
        <class>test.Request</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/test" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
        <!--    <property name="hibernate.cache.provider_class"
                value="org.hibernate.cache.EhCacheProvider" />  -->
            <property name="hibernate.connection.username" value="sa" />
        <!--    <property name="hibernate.connection.password" value="" /> 
            <property name="hibernate.jdbc.batch_size" value="50" /> -->
            <property name="hibernate.cache.use_second_level_cache" 
                value="false" /> 
            <property name="hibernate.hbm2ddl.auto" value="create" />
        <!--    <property name="hibernate.show_sql" value="true" /> 
            <property name="hibernate.max_fetch_depth" value="3" /> -->
        </properties>
    </persistence-unit>
</persistence>



/**
 * (Start,[Via1,Via2,..Vian], Ziel)
 */
package test;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.IndexColumn;
/**
 * @author Unkis
 *
 */
@Entity
@Table(name = "Request")
public class Request implements Serializable {
    private long id;
    private Collection timeStamps;
    private String type;
    private String virtServer;
    private String info;
    public Request() {
    }
    public Request(Collection timeStamps, String type, String virtServer,
            String info) {
        super();
        this.timeStamps = timeStamps;
        this.type = type;
        this.virtServer = virtServer;
        this.info = info;
    }
    public Request(String type, String virtServer, String info) {
        super();
        this.type = type;
        this.virtServer = virtServer;
        this.info = info;
    }
    @Id
    @Column(name = "request_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getVirtServer() {
        return virtServer;
    }
    public void setVirtServer(String virtServer) {
        this.virtServer = virtServer;
    }
    @ManyToMany(targetEntity = TimeStamp.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "time_request", joinColumns = @JoinColumn(name = "request_id"), inverseJoinColumns = @JoinColumn(name = "time_id"))
    public Collection getTimeStamps() {
        return timeStamps;
    }
    public void setTimeStamps(Collection locations) {
        this.timeStamps = locations;
    }
}



package test;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "time_request")
public class RequestTime implements Serializable {
    private long id;
    private Request request;
    private TimeStamp timeStamp;
    private int number;
    public RequestTime() {
        super();
        // TODO Auto-generated constructor stub
    }
    public RequestTime(int number, TimeStamp timeStamps, Request request) {
        super();
        this.request = request;
        this.timeStamp = timeStamps;
        this.number = number;
    }
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    @Basic
    @Column(nullable = false)
    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "time_id", nullable = false, updatable = false)
    public TimeStamp getTimeStamp() {
        return timeStamp;
    }
    public void setTimeStamp(TimeStamp timeStamp) {
        this.timeStamp = timeStamp;
    }
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "request_id", nullable = false, updatable = false)
    public Request getRequest() {
        return request;
    }
    public void setRequest(Request request) {
        this.request = request;
    }
}



package test;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class TimeStamp implements Serializable {
    //    private Long id;
    /**
     * Id of location
     */
    private Long time_id;
    private Collection resuests;
    private byte hour;
    private byte day;
    private byte month;
    private short year;
    public TimeStamp() {
        super();
        // TODO Auto-generated constructor stub
    }
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "location_id")
    public Long getTime_id() {
        return time_id;
    }
    public void setTime_id(Long location_id) {
        this.time_id = location_id;
    }
    public TimeStamp(Collection resuests, byte hour, byte day, byte month,
            short year) {
        super();
        this.resuests = resuests;
        this.hour = hour;
        this.day = day;
        this.month = month;
        this.year = year;
    }
    public TimeStamp(byte hour, byte day, byte month, short year) {
        super();
        this.hour = hour;
        this.day = day;
        this.month = month;
        this.year = year;
    }
    public byte getDay() {
        return day;
    }
    public void setDay(byte day) {
        this.day = day;
    }
    public byte getHour() {
        return hour;
    }
    public void setHour(byte hour) {
        this.hour = hour;
    }
    public byte getMonth() {
        return month;
    }
    public void setMonth(byte month) {
        this.month = month;
    }
    public short getYear() {
        return year;
    }
    public void setYear(short year) {
        this.year = year;
    }
    @ManyToMany(targetEntity = Request.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "time_request", joinColumns = @JoinColumn(name = "time_id"), inverseJoinColumns = @JoinColumn(name = "request_id"))
    public Collection getResuests() {
        return resuests;
    }
    public void setResuests(Collection resuests) {
        this.resuests = resuests;
    }
}
Re: Hibernate vs JDBC. Производительность.
От: Blazkowicz Россия  
Дата: 07.06.07 10:27
Оценка:
Здравствуйте, unkis, Вы писали:

U>Привет всем, у меня такая проблема, я заметил что при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC.

U>Вот я и подумал может, я не правильно использую Hibernate.

Как на счет того чтобы начать с небольшого RTFM?
Re[2]: Hibernate vs JDBC. Производительность.
От: unkis  
Дата: 07.06.07 10:51
Оценка:
U>>Привет всем, у меня такая проблема, я заметил что при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC.
U>>Вот я и подумал может, я не правильно использую Hibernate.

B>Как на счет того чтобы начать с небольшого RTFM?


читал я это, у меня отключён второй уровень cash, и сохраняю пока я не так много объектов(нет у меня проблемы с OutOfMemoryException ), поэтому мне не надо делать

session.flush();
session.clear();

вы бы с начало посмотрели, что у меня в конфиг. файле стоит, а потом отсылали меня к документации.

единственное что я не понял что это такое hibernate.jdbc.batch_size 20

За что этот размер отвечает?
Re: Hibernate vs JDBC. Производительность.
От: C0s Россия  
Дата: 07.06.07 10:58
Оценка:
Здравствуйте, unkis, Вы писали:

U>при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC.


для закачки данных с клиента стоит пользоваться batch-загрузкой,

а в идеале, если конкретная СУБД имеет нативные тулзы для загрузки данных, а серверный компьютер предоставляет файловый и управленчекский доступ (ssh в идеале или ftp+telnet), то можно генерировать текстовые файлы для загрузки, передавать их на сервер, там уже вызывать нужный тул. я это успешно делал для oracle, у него есть sqlldr, возможно, другие "хорошие" СУБД тоже что-то аналогичное предоставляют
Re[3]: Hibernate vs JDBC. Производительность.
От: C0s Россия  
Дата: 07.06.07 11:04
Оценка:
Здравствуйте, unkis, Вы писали:

U>единственное что я не понял что это такое hibernate.jdbc.batch_size 20

U>За что этот размер отвечает?

емнип, этот параметр отвечает за порционность чтения данных из зависимых коллекций, которые загружаются ленивым образом
Re[2]: Hibernate vs JDBC. Производительность.
От: unkis  
Дата: 07.06.07 11:13
Оценка:
C0s>для закачки данных с клиента стоит пользоваться batch-загрузкой,

Это что за загрузка такая? и как её пользоваться?

C0s>а в идеале, если конкретная СУБД имеет нативные тулзы для загрузки данных, а серверный компьютер предоставляет файловый и управленчекский доступ (ssh в идеале или ftp+telnet), то можно генерировать текстовые файлы для загрузки, передавать их на сервер, там уже вызывать нужный тул. я это успешно делал для oracle, у него есть sqlldr, возможно, другие "хорошие" СУБД тоже что-то аналогичное предоставляют


это всё хорошо, но потом надо будет не только вставлять, а перед этим ещё и делать выборку, так что текстовые файлы не подходят, хотя если hibernate в место comit мог бы сохранять в текстовые файлы, возможно это было бы приемлемо.
Re: Hibernate vs JDBC. Производительность.
От: b_manvelyan Украина  
Дата: 07.06.07 11:31
Оценка:
Здравствуйте, unkis, Вы писали:

Какое-то у Вас сравнение теплого с мягким. Чего Вы сравниваете Hibernate с batch загрузкой данных?
Re[3]: Hibernate vs JDBC. Производительность.
От: C0s Россия  
Дата: 07.06.07 11:35
Оценка: 1 (1)
Здравствуйте, unkis, Вы писали:

C0s>>для закачки данных с клиента стоит пользоваться batch-загрузкой,


U>Это что за загрузка такая? и как её пользоваться?


там, кажется, выше Blazkowicz дал ссылку

C0s>>а в идеале, если конкретная СУБД имеет нативные тулзы для загрузки данных, а серверный компьютер предоставляет файловый и управленчекский доступ (ssh в идеале или ftp+telnet), то можно генерировать текстовые файлы для загрузки, передавать их на сервер, там уже вызывать нужный тул. я это успешно делал для oracle, у него есть sqlldr, возможно, другие "хорошие" СУБД тоже что-то аналогичное предоставляют


U>это всё хорошо, но потом надо будет не только вставлять, а перед этим ещё и делать выборку, так что текстовые файлы не подходят, хотя если hibernate в место comit мог бы сохранять в текстовые файлы, возможно это было бы приемлемо.


это я предложил альтернативный путь (без hibernate/jdbc)... если идти таким путем, то данные обычно закачиваются в отдельные таблицы, а потом вызываются хранимые процеуры, которые уже и выборки нужные делают и данные перекладывают куда надо и как надо и т.п.

гибридный вариант, кстати, тоже возможен — загрузить данные описанным способом в те таблицы, которые тоже замаплены на hibernate, а потом работать в терминах select, insert from select и других массовых операций, доступных в hibernate 3.x
Re[3]: Hibernate vs JDBC. Производительность.
От: Blazkowicz Россия  
Дата: 07.06.07 12:07
Оценка: 1 (1)
Здравствуйте, unkis, Вы писали:

U>единственное что я не понял что это такое hibernate.jdbc.batch_size 20



In this chapter we'll show you how to avoid this problem. First, however, if you are doing batch processing, it is absolutely critical that you enable the use of JDBC batching, if you intend to achieve reasonable performance. Set the JDBC batch size to a reasonable number (say, 10-50):

Re[4]: Hibernate vs JDBC. Производительность.
От: C0s Россия  
Дата: 07.06.07 12:27
Оценка:
Здравствуйте, C0s, Вы писали:

U>>единственное что я не понял что это такое hibernate.jdbc.batch_size 20

U>>За что этот размер отвечает?

C0s>емнип, этот параметр отвечает за порционность чтения данных из зависимых коллекций, которые загружаются ленивым образом


сорри, попутало меня с fetch_size .... Blazkowicz правильно написал
Re[4]: Hibernate vs JDBC. Производительность.
От: unkis  
Дата: 07.06.07 13:12
Оценка:
B>

B>In this chapter we'll show you how to avoid this problem. First, however, if you are doing batch processing, it is absolutely critical that you enable the use of JDBC batching, if you intend to achieve reasonable performance. Set the JDBC batch size to a reasonable number (say, 10-50):


Вы меня извините но я всё равно не понял что это такое, у меня как раз стоит hibernate.jdbc.batch_size 50. могу поставить меньше только я не понимаю на что это влияет, что выставляет это значение.

Подскажите что подправить или объясните по подробней, ну не понимаю я, что это такое.



Какое-то у Вас сравнение теплого с мягким. Чего Вы сравниваете Hibernate с batch загрузкой данных?


Вы не могли бы объяснить что означает batch загрузка данных.
Re: Hibernate vs JDBC. Производительность.
От: Blazkowicz Россия  
Дата: 07.06.07 13:34
Оценка:
Здравствуйте, unkis, Вы писали:

U>Привет всем, у меня такая проблема, я заметил что при использовании Hibernate данные сохраняются во много раз меньше чем при использовании JDBC.

U>Вот я и подумал может, я не правильно использую Hibernate.

Вот ещё есть что почитать.
Re[2]: Hibernate vs JDBC. Производительность.
От: unkis  
Дата: 07.06.07 14:26
Оценка:
B>Вот ещё есть что почитать.

Ребята я бюсь над этой проблемой уже почти ниделю, у меня ничего не выходит, Batch processing мне не подходит из-за скорости, да он позволяет вставлять 1000000 обеъектов при этом не получив ошибку о переполнении памяти, но делает он это гараздо медленнее чем через JDBC.
Я так понимаю что предназначение Batch processing, как раз устранение ошибки OutOfMemoryException, с чем он прикрасно справлдяется, но ни как для скоростной вставки.

Я никак не пойму, неужели нет возможности в Hibernate записывать в базу обекты, хотя бы приблезительно так же быстро, как это можно сделать через JDBC?

Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.
Re[3]: Hibernate vs JDBC. Производительность.
От: Blazkowicz Россия  
Дата: 07.06.07 14:29
Оценка: 1 (1)
Здравствуйте, unkis, Вы писали:

U>Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.

Забиваешь гвозди микроскопом. ORM хорош в работе с деревьями объектов. При работе с большими объемами плоских данных в нем смысла собого нет. Напиши этот кусок на JDBC и не мучайся.
Re[4]: Hibernate vs JDBC. Производительность.
От: unkis  
Дата: 07.06.07 14:44
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, unkis, Вы писали:


U>>Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.

B>Забиваешь гвозди микроскопом. ORM хорош в работе с деревьями объектов. При работе с большими объемами плоских данных в нем смысла собого нет. Напиши этот кусок на JDBC и не мучайся.
это я сейчас привёл приер с тупым инсертом, а вдяльнейшем мне надо будет перед каждым инсёртом проверять существует ли такой объект или нет, тоесть делать выборку, и если существует то тогда один параметр этого объекта увеличить на один и update. и вот здесь hibernate был бы как раз кстати. так как он делал бы всего один update за всю транзакцию(мне так кажется что hibernate так и делает).

вот я тут ещё что хочу попробывать, если не поможет то буду писать всё без hibernate. 13.4. DML-style operations
но что-то у меня пока не получается сделать правильную вставку, я делаю так

Query q =entityManager.createQuery("insert into TimeStamp (hour,day,month,year) (4,1,1,2001) ");
int updatedItems = q.executeUpdate();


а он мне пишет

16:32:15,548 DEBUG JDBCContext:210 - after transaction begin
16:32:15,548 DEBUG QueryPlanCache:70 - unable to locate HQL query plan in cache; generating (insert into TimeStamp (hour,day,month,year) (4,1,1,2001) )
16:32:15,579 DEBUG QueryTranslatorImpl:246 - parse() - HQL: insert into TimeStamp (hour,day,month,year) (4,1,1,2001) 
16:32:15,579 ERROR PARSER:33 - line 1:45: unexpected token: (
16:32:15,579 DEBUG ErrorCounter:28 - line 1:45: unexpected token: (
line 1:45: unexpected token: (
    at org.hibernate.hql.antlr.HqlBaseParser.selectFrom(HqlBaseParser.java:1122)
    at org.hibernate.hql.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:702)
    at org.hibernate.hql.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:296)
    at org.hibernate.hql.antlr.HqlBaseParser.insertStatement(HqlBaseParser.java:328)
    at org.hibernate.hql.antlr.HqlBaseParser.statement(HqlBaseParser.java:165)
    at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:248)
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
    at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
    at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
    at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
    at MainTest.start(MainTest.java:71)
    at MainTest.<init>(MainTest.java:40)
    at MainTest.main(MainTest.java:124)
16:32:15,579 DEBUG AST:266 - --- HQL AST ---
 \-[INSERT] 'insert'
    +-[INTO] 'into'
    |  +-[IDENT] 'TimeStamp'
    |  \-[RANGE] 'column-spec'
    |     +-[IDENT] 'hour'
    |     +-[IDENT] 'day'
    |     +-[IDENT] 'month'
    |     \-[IDENT] 'year'
    \-[QUERY] 'query'

Exception in thread "main" org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ( near line 1, column 45 [insert into TimeStamp (hour,day,month,year) (4,1,1,2001) ]
    at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:31)
    at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:24)
    at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:59)
    at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:258)
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
    at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
    at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
    at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
    at MainTest.start(MainTest.java:71)
    at MainTest.<init>(MainTest.java:40)
    at MainTest.main(MainTest.java:124)


как должен правельно выглядеть insert в таком случаи?
Re[5]: Hibernate vs JDBC. Производительность.
От: Blazkowicz Россия  
Дата: 07.06.07 14:50
Оценка:
Здравствуйте, unkis, Вы писали:

U>это я сейчас привёл приер с тупым инсертом, а вдяльнейшем мне надо будет перед каждым инсёртом проверять существует ли такой объект или нет, тоесть делать выборку, и если существует то тогда один параметр этого объекта увеличить на один и update. и вот здесь hibernate был бы как раз кстати. так как он делал бы всего один update за всю транзакцию(мне так кажется что hibernate так и делает).

Такие вещи вообше надо в базе писать всякими процедурами и триггерами.

U>
U>Query q =entityManager.createQuery("insert into TimeStamp (hour,day,month,year) (4,1,1,2001) ");
U>int updatedItems = q.executeUpdate();
U>


U>а он мне пишет

U>16:32:15,579 DEBUG ErrorCounter:28 — line 1:45: unexpected token: (
U>как должен правельно выглядеть insert в таком случаи?
Все верно пишет.
Re[5]: Hibernate vs JDBC. Производительность.
От: Blazkowicz Россия  
Дата: 07.06.07 14:52
Оценка: 1 (1)
Здравствуйте, unkis, Вы писали:

U>вот я тут ещё что хочу попробывать, если не поможет то буду писать всё без hibernate.

А что за крайности всё или ничего. Напиши критические участки на том же JDBC и не мучайся. Хибер он же в основном проиводительность программера увеличивает а не системы.
Re[3]: Hibernate vs JDBC. Производительность.
От: Trean Беларусь http://axamit.com/
Дата: 07.06.07 14:56
Оценка:
Здравствуйте, unkis, Вы писали:



B>>Вот ещё есть что почитать.


U>Ребята я бюсь над этой проблемой уже почти ниделю, у меня ничего не выходит, Batch processing мне не подходит из-за скорости, да он позволяет вставлять 1000000 обеъектов при этом не получив ошибку о переполнении памяти, но делает он это гараздо медленнее чем через JDBC.


У меня была абсолютно та же проблема с JPA. В рамках одной транзакции не очищается кэш сессии, т.е. надо разбивать на транзакции, чтобы исключение не бросалось. Hibernate же не знает, что объект вам не понадобится больше.

U>Я так понимаю что предназначение Batch processing, как раз устранение ошибки OutOfMemoryException, с чем он прикрасно справлдяется, но ни как для скоростной вставки.


batch updates, в JDBC во всяком случае, нужны чтобы не создавать каждый раз отдельный запрос, а передавать данные пачками.

U>Я никак не пойму, неужели нет возможности в Hibernate записывать в базу обекты, хотя бы приблезительно так же быстро, как это можно сделать через JDBC?


Используйте загрузку данных из файла скриптом, как мне посоветовали. Самый быстрый способ.

U>Что я делаю не так, ну подскожите пожалуйста, ткните пальцом.


Модель использования ORM совсем другая. Глупо использовать ORM, скажем, для Time-Series.
Re[6]: Hibernate vs JDBC. Производительность.
От: unkis  
Дата: 07.06.07 15:07
Оценка:
B>Такие вещи вообше надо в базе писать всякими процедурами и триггерами.

Я об этом думал, но останавливает меня две вещи.
1) писать тригер или процедуру, это привязать себя к конкретной базе данных. что конечно не критично, но не хотелось бы.
2) как будет вести себя тригер, если он не успеет сделать выборку или посчитать что-то, как к ниму приходит уже новый инсёрт, если он их будет обрабатывать по очереди, то тогда ничего страшного, но если каждый отдельно то получится каша, на чей совести остаётся проблема синхронизации?
Re[7]: Hibernate vs JDBC. Производительность.
От: unkis  
Дата: 07.06.07 15:10
Оценка:
Здравствуйте, unkis, Вы писали:


B>>Такие вещи вообше надо в базе писать всякими процедурами и триггерами.


U>Я об этом думал, но останавливает меня две вещи.

U>1) писать тригер или процедуру, это привязать себя к конкретной базе данных. что конечно не критично, но не хотелось бы.
U>2) как будет вести себя тригер, если он не успеет сделать выборку или посчитать что-то, как к ниму приходит уже новый инсёрт, если он их будет обрабатывать по очереди, то тогда ничего страшного, но если каждый отдельно то получится каша, на чей совести остаётся проблема синхронизации?

да и в каком случаи использовать триггеры, а в каком хранимые процедуры?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.