#DocumentId on a Non-#Id Field Seems to Make Indexing Invalid for Existing Data in Database - hibernate-search

I have a class named Book that contains 2 fields, id and isbn.
And I want to perform normal Hibernate queries using the id field as the primary key, while perform Hibernate Search queries using the isbn field as the primary key.
So I put the #Id annotation on the id field and the #DocumentId annotation on the isbn field, as follows.
#Entity
#Indexed
public class Book {
#Id
private Long id;
#DocumentId(name = "_documentId")
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private Long isbn;
...
}
Then I found that, after the Hibernate Search indexing process starts, although all new updates to the Book entities are correctly indexed, the existing Book entities in the database are not indexed.
And after I move the #DocumentId annotation from the isbn field onto the the id field as follows, the existing Book entities in the database will be indexed again when the Hibernate Search indexing process starts.
#Entity
#Indexed
public class Book {
#Id
#DocumentId(name = "_documentId")
private Long id;
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private Long isbn;
...
}
So my question is
Can the Hibernate Search indexing process work same as before, even when the #DocumentId and #Id annotations are on different fields?.
I use the Luke to check the Hibernate Search index.
Libraries
hibernate-search-orm: 5.5.4.Final
hibernate-core: 5.0.3.Final
jdk: 1.7.0_79
Code
Entity Class
Book.java
#Entity
#Indexed
public class Book {
#Id
private Long id;
#DocumentId(name = "_documentId")
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private Long isbn;
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private int version;
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private String content;
public Book() {
}
public Book(Long isbn, int version, String content) {
this.isbn = isbn;
this.version = version;
this.content = content;
}
#Override
public String toString() {
return "Book [id=" + id + ", isbn=" + isbn + ", version=" + version + ", content=" + content + "]";
}
// Getters and setters...
}
Hibernate Mapping File
Book.hbm.xml
<hibernate-mapping package="com.raychen518.study.hibernate">
<class name="Book" table="BOOKS">
<id name="id" column="ID">
<generator class="increment" />
</id>
<property name="isbn" column="ISBN" />
<property name="version" column="VERSION" />
<property name="content" column="CONTENT" />
</class>
</hibernate-mapping>
Hibernate Configuration File
hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/test</property>
<property name="connection.username">postgres</property>
<property name="connection.password">admin</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">validate</property>
<property name="hibernate.search.lucene_version">LUCENE_CURRENT</property>
<property name="hibernate.search.default.directory_provider">filesystem</property>
<property name="hibernate.search.default.indexBase">hibernate.search.test/lucene/indexes</property>
<mapping resource="Book.hbm.xml" />
</session-factory>
</hibernate-configuration>
Application Launcher Class
BookManager.java
After executing the main(String[]) method in the class, the Book entity which the isbn field is 789 will be created in the index while the existing Book entities (in database) which the isbn fields are 123 and 456 respectively are not indexed.
public class BookManager {
public static void main(String[] args) throws InterruptedException {
BookManager manager = new BookManager();
manager.startIndexing();
manager.saveSome();
}
private void startIndexing() throws InterruptedException {
FullTextSession fullTextSession = Search.getFullTextSession(HibernateUtil.getSessionFactory().openSession());
fullTextSession.createIndexer(Book.class).startAndWait();
}
public void saveSome() {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
// session.save(new Book(123L, 1, "abc"));
// session.save(new Book(456L, 1, "def"));
session.save(new Book(789L, 1, "ghi"));
session.getTransaction().commit();
session.close();
}
}
HibernateUtil.java
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
return new MetadataSources(registry).buildMetadata().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}

Related

Java.lang.reflect.invocationTargetException in hibernate

Any one please solve my problem. I'm getting java.lang.reflect.invocationTargetException while I'm trying to save an object into oracle database(Oracle 10G).
Here is my model class named Student.java
package org.hibernatetest;
public class Student {
private int id;
private String name;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Here is my mapping file named Student.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.hibernatetest.Student" table="STUDENT_2018">
<id name="id" column="STUDENT_ID"/>
<property name="name" column="STUDENT_NAME"></property>
<property name="email" column="STUDENT_EMAIL"></property>
</class>
</hibernate-mapping>
here is configuration file named as hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.username">Test</property>
<property name="hibernate.connection.password">Test</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#localhost:1521:XE</property>
<property name="hibernate.hbm2ddl.auto">create-drop</property>
<property name="show_sql">true</property>
<mapping resource="resource/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
here is my persistent class named Test.java
package org.hibernatetest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test {
public static void main(String[] args) {
Student st = new Student();
st.setId(1);
st.setName("Mohan");
st.setEmail("mmohan668#gmail.com");
Configuration cfg = new Configuration();
SessionFactory sf = cfg.configure("resource/hibernate.cfg.xml").buildSessionFactory();
Session s = sf.openSession();
s.save(st);
s.beginTransaction().commit();
s.evict(st);
}
}
Please help to resolve my problem . Thanks in advance.

How to persist several rows in a #OneToMany relationship with a composite key

I have found this OLD link which resolve my database schema:
http://randomthoughtsonjavaprogramming.blogspot.com.es/2014/09/jpa-manytoone-with-composite-primary-key.html
I can retrieve data and everything works great, but I don't know how to insert data as I posted to the author.
In my case for every guild inserted I need to insert several guildranks at the same time, so one use case will be:
BEGIN TRANSACTION
GUILD
Guildname1
GUILDRANK
Guildname1, 1
Guildname1, 2
Guildname1, 3
Guildname1, 4
END TRANSACTION
Any suggestions?
Thanks
UPDATE
#Entity
#NamedQueries({
#NamedQuery(name = "Cuestionario.findAll", query = "SELECT c FROM Cuestionario c")
})
public class Cuestionario implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "ID", nullable = false)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#OneToMany(mappedBy = "cuestionario", cascade = { CascadeType.PERSIST })
private Set<Hoja> hojas;
}
#Entity
#NamedQuery(name = "Hoja.findAll", query = "SELECT h FROM Hoja h")
public class Hoja implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private HojaPK id;
// bi-directional many-to-one association to Cuestionario
#ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
#JoinColumn(name = "ID", insertable = false, updatable = false)
private Cuestionario cuestionario;
public Hoja() {
}
}
#Embeddable
public class HojaPK implements Serializable {
// default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
//Correspond with "id" in Cuestionario
#Column(name = "ID")
private long id;
private int dia;
public HojaPK() {
}
}
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="pu"
transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.user" value="***" />
<property name="javax.persistence.jdbc.password" value="***" />
<property name="javax.persistence.jdbc.url"
value="jdbc:sqlserver://localhost:1433;databaseName=mydatabase" />
<property name="javax.persistence.jdbc.driver"
value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
<property name="hibernate.show_sql" value="true" />
<!--
<property name="hibernate.hbm2ddl.auto" value="update" />
-->
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
</properties>
</persistence-unit>
</persistence>
TestCase.java
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(cuestionario);
em.flush();
for (int i = 0; i <= 32; i++) {
HojaPK hojaPk = new HojaPK(cuestionario.getId(), i);
Hoja hoja = new Hoja();
hoja.setId(hojaPk);
em.persist(hoja);
}
em.getTransaction().commit();
em.close();
emf.close();

JPA entity returns null while database is not empty

I am developing a Java web application with I am using netbeans 8 as IDE and glassfissh as the server I am trying to fetch data from Users table in the database I need to use JPA as data model layer for this purpose,
edited
although the Entity is generated by netbeans from a table in the MySQL database which has some rows the resultList which is returned from the executing the query returns no rows from a table in Derby database and it is empty
in the following I provided my Entity Java bean code which is automatically generated by netbeans IDE
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* #author Home
*/
#Entity
#Table(name = "users")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
#NamedQuery(name = "Users.findById", query = "SELECT u FROM Users u WHERE u.id = :id"),
#NamedQuery(name = "Users.findByName", query = "SELECT u FROM Users u WHERE u.name = :name"),
#NamedQuery(name = "Users.findByEmail", query = "SELECT u FROM Users u WHERE u.email = :email"),
#NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password"),
#NamedQuery(name = "Users.findByRememberToken", query = "SELECT u FROM Users u WHERE u.rememberToken = :rememberToken"),
#NamedQuery(name = "Users.findByCreatedAt", query = "SELECT u FROM Users u WHERE u.createdAt = :createdAt"),
#NamedQuery(name = "Users.findByUpdatedAt", query = "SELECT u FROM Users u WHERE u.updatedAt = :updatedAt")})
public class Users implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "name")
private String name;
// #Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "email")
private String email;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "password")
private String password;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "remember_token")
private String rememberToken;
#Basic(optional = false)
#NotNull
#Column(name = "created_at")
#Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
#Basic(optional = false)
#NotNull
#Column(name = "updated_At")
#Temporal(TemporalType.TIMESTAMP)
private Date updatedAt;
public Users() {
}
public Users(Integer id) {
this.id = id;
}
public Users(Integer id, String name, String email, String password, String rememberToken, Date createdAt, Date updatedAt) {
this.id = id;
this.name = name;
this.email = email;
this.password = password;
this.rememberToken = rememberToken;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRememberToken() {
return rememberToken;
}
public void setRememberToken(String rememberToken) {
this.rememberToken = rememberToken;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Users)) {
return false;
}
Users other = (Users) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "some string";
}
}
and this is my Servlet code where I try to get the Users of database
#PersistenceUnit
EntityManagerFactory emf;
emf.createEntityManager().createNamedQuery("Users.findAll").getResultList().size()
but the ResultList did not fetch any data from database
this is the log from the server which shows iit is connected to Derby
Config: Connected: jdbc:derby://localhost:1527/sun-appserv-samples;;create=true
User: APP
Database: Apache Derby Version: 10.10.1.3 - (1557168)
Driver: Apache Derby Network Client JDBC Driver Version: 10.10.2.0 - (1582446)
edited
whil based on configuration I think it is supposed to connect to MySQL this is my glassfish-resources.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false"
connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10"
connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit"
datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false"
idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true"
lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false"
max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="mysql_mysql_rootPool"
non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.ConnectionPoolDataSource"
statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0"
wrap-jdbc-objects="false">
<property name="serverName" value="localhost"/>
<property name="portNumber" value="3306"/>
<property name="databaseName" value="mydatabase"/>
<property name="User" value="root"/>
<property name="Password" value=""/>
<property name="URL" value="jdbc:mysql://localhost:3306/mydatabase"/>
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
</jdbc-connection-pool>
<jdbc-resource enabled="true" jndi-name="realestateConnection" object-type="user" pool-name="mysql_mysql_rootPool"/>
</resources>
and this is my persistence.xml file
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="architectsPU" transaction-type="JTA">
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
</persistence>
edited
please help me how to solve this issue and how can change the config in order to get connected to the right database when deploying the file that tells server which data source to connect is it same as `persistence.xml? and if not where is it located?
As the comments on the question state clearly enough, your JPA provider is using Apache Derby for database rather than what you wanted (mySQL). This is because your persistence.xml doesn't bother specifying what datasource(s) to use. You need to specify jtaDataSource (and maybe also nonJtaDataSource) to point to your JTA MySQL DataSource so then the JPA provider has the information it needs to use your DataSource.

JPA Create Parent/child relationship with a lot of children

I am trying to store entity Track with children entities TrackPoints with JPA method create. However, to store Track with its children TrackPoints last really long - about 30 seconds. I tried GenerationType.Identity and GenerationType.SEQUENCE. If I also have Hibernate Spatial (Postgis) column, it lasts even longer - about 60 seconds to store parent and all children. JPA sends insert sequentially one followed by another. How can I optimize this? Can anybody tell me what is the main problem?
Technologies:
Wildfly 8.1, JPA 2.1 (hibernate), Hibernate Spatial, EJB, JTA
PostgreSQL 9.3 + PostGis - default setup (just install from Ubuntu package)
Track.java
#Entity
#Table(name = "TRACKS")
public class Track implements Serializable {
#Id
#Column(name = "track_id", nullable = false, unique = true)
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
#NotNull
#NotEmpty
#Size(min = 1, max = 100)
#Column(nullable = false, length = 100)
private String name;
#Size(max = 200)
#Column(nullable = false, length = 200)
private String description;
#OneToOne(optional = false)
#JoinColumn(name = "userId", nullable = false)
private User userOwner;
#NotNull
#NotEmpty
#Column(nullable = false, length = 55)
private String type;
#NotNull
private Boolean isShared;
#OneToMany(mappedBy = "track")
private List<TrackPoint> trackPoints;
}
TrackPoint.java
#Entity
#Table(name = "TRACK_POINTS")
public class TrackPoint implements Serializable {
private static final long serialVersionUID = 8089601593251025235L;
#Id
#Column(name = "trackpoint_id", nullable = false, unique = true)
#GeneratedValue(generator = "track_point_sequence", strategy = GenerationType.SEQUENCE)
#SequenceGenerator(name = "track_point_sequence", sequenceName = "track_point_sequence", allocationSize = 1000)
private Long id;
#NotNull
private int trackSegment;
#NotNull
private double elevation;
#NotNull
#Temporal(TemporalType.TIMESTAMP)
private Date timeStamp;
#NotNull
#ManyToOne(optional = false, fetch = FetchType.EAGER)
#JoinColumn(name = "track_id")
private Track track;
/*Hibernate Spatial - Postgis field.
#NotNull
#Column(nullable = false)
#Type(type = "org.hibernate.spatial.GeometryType")
private Geometry location;*/
}
TrackService.java
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public class TracksService implements ITracksService {
#Inject
private IDaoService dao;
#Override
public Long createTrack(GpxType gpx, String userId, String name, String desc) {
// Map GPX to Track, TrackPoint object.
track = dao.create(track);
int batch_size = 50;
int i = 0;
for(TrackPoint point: track.getTrackPoints()) {
dao.create(point);
if(i++ % batch_size == 0) {
dao.flush();
dao.clear();
}
}
return track.getId();
}
DaoService.java
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public class DaoService implements IDaoService {
#PersistenceContext()
private EntityManager em;
#Override
public <T extends Serializable> T create(T t) {
em.persist(t);
return t;
}
}
persistence.xml
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xsi:schemaLocation=
"http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="postgisTourbookPU" transaction-type="JTA">
<description>PostgresSQL database with PostGIS extension</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>${tourbook.datasource.postgresql.jndi-name}</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<!-- JPA properties -->
<property name="javax.persistence.schema-generation.database.action"
value="drop-and-create"/>
<!-- <property name="javax.persistence.schema-generation-target"
value="database"/>-->
<!-- Creation Schema Properties -->
<property name="javax.persistence.schema-generation.create-source"
value="metadata"/>
<!-- <!– DDL Script location, when script is used –>
<property name="javax.persistence.schema-generation.create-script-source"
value="META-INF/create-script.sql"/>-->
<!-- Drop Schema Properties -->
<property name="javax.persistence.schema-generation.drop-source"
value="metadata"/>
<!-- <property name="javax.persistence.schema-generation.drop-script-source"
value="META-INF/drop-script.sql"/>-->
<property name="javax.persistence.sql-load-script-source"
value="META-INF/load-script.sql"/>
<!-- JPA driver information -->
<property name="javax.persistence.jdbc.driver"
value="org.postgresql.Driver"/>
<!-- Hibernate properties -->
<property name="hibernate.connection.characterEncoding"
value="UTF-8"/>
<property name="hibernate.dialect"
value="org.hibernate.spatial.dialect.postgis.PostgisDialect"/>
<property name="hibernate.default_schema"
value="public"/>
<property name="hibernate.show_sql"
value="true"/>
<property name="hibernate.jdbc.batch_size" value="50"/>
<property name="hibernate.jdbc.fetch_size"
value="50"/>
<property name="hibernate.order_inserts"
value="true"/>
<property name="hibernate.order_updates"
value="true"/>
<property name="hibernate.cache.use_query_cache"
value="false"/>
<!-- Hibernate caching -->
</properties>
</persistence-unit>
</persistence>
Edited
So I have tried, batch insert in Hibernate, but I still get 30 seconds for saving 2000 points.
you're inserting a parent with all the children. In that case the Hibernate JPA indeed can be slow, but there are a few tips to improve the performance
- check the hibernate batch guide http://docs.jboss.org/hibernate/core/4.0/devguide/en-US/html/ch04.html
- I've used the hibernate.jdbc.batch_size parameter (set to e.g. 50)
Good luck
Gabriel

GAE : Google Cloud SQL + JPA is not working

When i connected my cloud sql instance with JPA using EclipseLink 2.2.1, it shows following error
W 2012-10-24 12:21:46.120
org.datanucleus.metadata.xml.AbstractMetaDataHandler error: MetaData Parser encountered an error in file "file:/base/data/home/apps/s~appengineaplicationID/8.362672796318745816/WEB-INF/classes/META-INF/persistence.xml" at line 2, column 248 : cvc-complex-type.3.1: Value '2.0' of attribute 'version' of element 'persistence' is not valid with respect to the corresponding attribute use. Attribute 'version' has a fixed value of '1.0'. - Please check your specification of DTD and the validity of the MetaData XML that you have specified.
W 2012-10-24 12:21:46.885
Error for /jpatest
java.lang.ExceptionInInitializerError
at com.my.jpa.ContactService.createContact(ContactService.java:20)
at com.my.jpa.JPATestServlet.doGet(JPATestServlet.java:16)
Caused by: org.datanucleus.exceptions.NucleusUserException: No available StoreManager found for the datastore URL key "". Please make sure you have all relevant plugins in the CLASSPATH (e.g datanucleus-rdbms?, datanucleus-db4o?), and consider setting the persistence property "datanucleus.storeManagerType" to the type of store you are using e.g rdbms, db4o
W 2012-10-24 12:21:46.887
Nested in java.lang.ExceptionInInitializerError:
javax.persistence.PersistenceException: Provider error. Provider: org.datanucleus.jpa.PersistenceProviderImpl
at javax.persistence.Persistence.createFactory(Persistence.java:176)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:112)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:66)
at com.my.jpa.EMF.<clinit>(EMF.java:8)
at com.my.jpa.ContactService.createContact(ContactService.java:20)
at com.my.jpa.JPATestServlet.doGet(JPATestServlet.java:16)
C 2012-10-24 12:21:46.893
Uncaught exception from servlet
java.lang.ExceptionInInitializerError
at com.my.jpa.ContactService.createContact(ContactService.java:20)
at com.my.jpa.JPATestServlet.doGet(JPATestServlet.java:16)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
My code for persistance.xml is
<?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="JPATest">
<class>com.my.jpa.Contact</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.google.cloud.sql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:google:rdbms://instance_name/db" />
<property name="javax.persistence.jdbc.user" value="" />
<property name="javax.persistence.jdbc.password" value="" />
</properties>
</persistence-unit>
</persistence>
My Entity Manager Factory Class is :
public final class EMF {
private static final EntityManagerFactory emfInstance = Persistence
.createEntityManagerFactory("JPATest");
private EMF() {
}
public static EntityManagerFactory get() {
return emfInstance;
}
}
Servlet is :
public class JPATestServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
ContactService service = new ContactService();
service.createContact(new Contact("Manu", "Mohan", "686019", "TVM"));
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
}
}
Entity Class is :
#Entity
public class Contact {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String phoneNumber;
private String address;
public Contact() {
}
public Contact(String fn, String ln, String pn, String addr) {
this.firstName = fn;
this.lastName = ln;
this.phoneNumber = pn;
this.address = addr;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
One would think that if you want to use EclipseLink, then you would set the "provider" in "persistence.xml", since you have other JPA implementation(s) in the CLASSPATH too, or alternatively you fix the CLASSPATH to make sure there is only 1 JPA implementation present