简体   繁体   中英

Hibernate JPA + OSGi + SQLite, how?

I am having problem to integrate the Hibernate JPA with OSGi (Apache Aries) and the SQLite database. The problem is that the Hibernate is not able to persist the entity class into the table. There is no error to indicate any problem occurred when persisting the entity class but I don't see the SQL insert statement is generated by the Hibernate which does for Derby database.

So when I call like this:

People aPeople = new PeopleImpl();
aPeople.setAddress("555 abc st, richmond");
aPeople.setName("AAA Smith");
aPeople.setNumber(555555);

PeoplePersistenceService peoplePersistenceService = 
    peoplePersistenceServiceTracker.getService();

peoplePersistenceService.AddPeople(aPeople);

The aPeople will not be inserted into the table.

The current configurations I have work for Derby so I assume the major parts should be correct but I might be missing some SQLite specific stuff. I did a lot search but I couldn't find an example for Hibernate JPA AND OSGi AND SQLite.

I created the SQLite bundle by wrapping the xerial sqlite jdbc v3.7.15-M1. Also I copied the SQLite dialect code from internet ( http://code.google.com/p/hibernate-sqlite/source/browse/trunk/source/src/main/java/com/applerao/hibernatesqlite/dialect/SQLiteDialect.java ) to build the hibernate dialect.

I really appropriate if someone can show me the correct configurations that work for this case or point me the right track.

The following are my settings, and please let me know if you need any other information.

datasource.xml:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            default-activation="lazy">

    <bean id="sqliteDataSource" class="org.sqlite.SQLiteDataSource">
        <property name="url" value="jdbc:sqlite:aeServerDatabase.db"/>
    </bean>

    <service ref="sqliteDataSource" interface="javax.sql.DataSource">
        <service-properties>
            <entry key="osgi.jndi.service.name" value="jdbc/sqlite/AeServerDatabase" />
        </service-properties>
    </service>
</blueprint>

persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<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 persistence_2_0.xsd"
                version="2.0">

   <persistence-unit name="peopleExampleSQLite" transaction-type="RESOURCE_LOCAL">
       <description>Persistence Unit for the People Persistence Example with SQLite</description>
       <provider>org.hibernate.ejb.HibernatePersistence</provider>
       <non-jta-data-source>osgi:service/jdbc/sqlite/AeServerDatabase</non-jta-data-source>
       <class>ae.bundles.services.dal.example.PeopleImpl</class>
       <exclude-unlisted-classes>true</exclude-unlisted-classes>

       <properties>
<!--            <property name="javax.persistence.jdbc.driver" value="org.sqlite.JDBC"/> -->
<!--            <property name="javax.persistence.jdbc.url" value="jdbc:sqlite:aeServerDatabase.db"/> -->
<!--            <property name="hibernate.connection.driver_class" value="org.sqlite.JDBC"/> -->
<!--            <property name="hibernate.connection.url" value="jdbc:sqlite:aeServerDatabase.db"/> -->

<!--             The special SQL dialect for SQLite  -->
           <property name="hibernate.dialect" value="ae.bundles.services.dal.dialect.SQLiteDialect"/>
           <property name="hibernate.hbm2ddl.auto" value="create"/>

           <property name="hibernate.show_sql" value="true"/>
           <property name="hibernate.format_sql" value="true"/>
       </properties>
   </persistence-unit>

</persistence>

The blueprint.xml:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"
    xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.1.0"
    default-activation="lazy">

    <bean id="peoplePersistenceImpl"
        class="ae.bundles.services.dal.example.PeoplePersistenceServiceImpl">
        <tx:transaction method="*" value="Required"/>
        <jpa:context property="entityManager" unitname="peopleExampleSQLite" />
    </bean>

    <service ref="peoplePersistenceImpl"
        interface="ae.bundles.services.dal.example.PeoplePersistenceService" />

</blueprint>

The entity class:

package ae.bundles.services.dal.example;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class PeopleImpl implements People
{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private Integer number;
    private String address;

    public void setName(String name) 
    {
        this.name = name;
    }

    public String getName() 
    {
        return name;
    }

    public void setNumber(Integer num) 
    {
        this.number = num;
    }

    public Integer getNumber() 
    {
        return number;
    }

    public void setAddress(String address) 
    {
        this.address = address;
    }

    public String getAddress() 
    {
        return address;
    }

    public Long getId()
    {
        return id;
    }

}

The persistence class:

package ae.bundles.services.dal.example;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;

public class PeoplePersistenceServiceImpl implements PeoplePersistenceService 
{
    private EntityManager em;

    public PeoplePersistenceServiceImpl() {}

    public void setEntityManager(EntityManager em)
    {
        this.em = em;
    }

    public void AddPeople(People p) 
    {
        em.persist(p);
    }

    public People getPeopleByName(String name) 
    {
        String query = "SELECT e FROM PeopleImpl e" +
                " WHERE e.name = '" + name + "'";

        People p = null;

        try
        {
            p = em.createQuery(query, People.class).getSingleResult();
        }
        catch (NoResultException e)
        {
            return null;
        }
        catch (NonUniqueResultException e)
        {
            System.out.println("More than one result available!");
            return null;
        }

        return p;
    }

    public void updatePeopleName(People p, String newName)
    {
        //People target = em.find(PeopleImpl.class, p.getId());
        People target = getPeopleByName(p.getName());

        if (target != null)
        {
            target.setName(newName);
            em.flush();
        }
    }

    public void removePeople(People p) 
    {
        //People target = em.find(PeopleImpl.class, p.getId());
        People target = getPeopleByName(p.getName());

        if (target != null)
        {
            em.remove(target);
            em.flush();
        }
    }

}

Do your get/update/remove methods work? If so, your configuration will be ok and you will simply need to add a flush to your insert method. I have not used hibernate this way, so I cannot speak as to whether or not your configuration is correct. Either way, you should be flushing after the insert if you want this data to be persisted from the first level cache into your database. Hope this helps.

I had the same Problem with AEM cms, it works also with OSGI.

My anwer is posted here: AEM CQ with JPA (Hibernate)

I hope it will help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM