persistence etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
persistence etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

13 Aralık 2010 Pazartesi

persistence using jpa

I have one database, but the atomicity of transactions is large. In other words, many entities must be manipulated in one transaction. Therefore, the design is something like that:
  • a general superclass entity that holds shared stuff amongst all other entities that are subject to be persisted.
  • an entity manager class that is responsible for creation of emf and em.
  • a general dao for the superclass mentioned above, to accomplish shared, general persistence tasks (crud operations - create, retrieve, update, delete ). The entity class type and an entity manager is injected to this dao.
  • specific dao classes for entities that needs operations other than crud. Something to note down is that since transaction management must be done in an upper layer in this case, no begin, commit or rollback transaction operation appear at dao (persistence) layer.
// general superclass
@MappedSuperclass
public class MyBean implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id = -1L;
// ...
}

//////////////////////////////////////////////////////////////
// a specific class
public class SpecificBean extends MyBean {
// ...
}

//////////////////////////////////////////////////////////////
// entity manager class
public class MyEntityManager {

private static final String PERSISTENCE_UNIT = "MyPU";

@PersistenceUnit(unitName = PERSISTENCE_UNIT)
private EntityManagerFactory emf;

public EntityManager getEm() {
if (emf == null) {
emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
}
return emf.createEntityManager();
}
}

//////////////////////////////////////////////////////////////
// general dao for superclass MyBean
public class MyBeanDao {

private Class clazz;
protected EntityManager em;

public MyBeanDao(Class clazz, EntityManager em) {
this.clazz = clazz;
this.em = em;
}

public void create(MyBean bean) {
em.persist(bean);
}

public MyBean retrieve(Long id) {
return (MyBean) em.find(this.clazz, id);
}

public void remove(Long id) {
MyBean bean = retrieve(id);
if (bean != null) {
em.remove(bean);
}
}

public MyBean update(MyBean bean) {
MyBean updated = em.merge(bean);
return updated;
}

public void closeEm() {
em.close();
}

public void initTransaction() {
em.getTransaction().begin();
}

public void finishTransaction() {
em.getTransaction().commit();
}

public void rollbackTransaction() {
em.getTransaction().rollback();
}
}

//////////////////////////////////////////////////////////////
// specific dao classes
public class SpecificDao extends MyBeanDao {

public SpecificDao (EntityManager em) {
super(SpecificBean.class, em);
}
// extra methods
}

//////////////////////////////////////////////////////////////
// sample call

MyEntityManager mem = new MyEntityManager ();
EntityManager em = mem.getEm();

SpecificDao dao = new SpecificDao (em);

dao.initTransaction();
// do something
// ....
dao.finishTransaction();



more effective solutions may exist.. this is just a sample design..

6 Ekim 2009 Salı

notes on schuchert jpa tutor 4

finally the last tutor at http://schuchert.wikispaces.com/JPA+Tutorial+4+-+Inheritance+and+Polymorphic+Queries

lets move!
now, all tests should pass..
well, time to go to my own project, thanks to schuchert, tutors are really helpful :)

notes on schuchert jpa tutor 3

now the tutor i follow is http://schuchert.wikispaces.com/JPA+Tutorial+3+-+A+Mini+Application

lets see what happens..

so perfect, just in test methods of LibraryTest, the assertEquals methods used to compare floats that take 2 params are deprecated. Instead define a delta as follows and pass it as 3rd param to mentioned methods. Thus, tests will pass i think :)
private static final float DELTA = (float) 0.0;
...
assertEquals(.., .., DELTA);




5 Ekim 2009 Pazartesi

notes on schuchert jpa tutor 2

the tutor is at http://schuchert.wikispaces.com/JPA+Tutorial+2+-+Working+with+Queries+1

lets follow..
  • comment out the exception in the  unsuccessfulSingleResultTooManyEntries  test case of QueriesTest.. thus, it will pass..
 @Test// (expected = NonUniqueResultException.class)
    public void unsuccessfulSingleResultTooManyEntries() {
insertPerson();
        insertPerson();

        // This will fail because we expect a single result
        // but in fact there are 2 results returned.
        em.createQuery("from Person").getSingleResult();
    }

this is because,  getSingleResult() does not get angry when there are more than one records and just picks the first one..



4 Ekim 2009 Pazar

notes on schuchert jpa tutor 1

i am following schuchert's jpa tutor 1 at http://schuchert.wikispaces.com/JPA+Tutorial+1+-+Getting+Started
however, my environment is netbeans 6.5 + glassfish v2 + postgre..
lets note down some drawbacks i faced:
  • i get the following error while trying to run PersonTest :
Testcase: emptyTest(entity.PersonTest):        Caused an ERROR
[PersistenceUnit: SchuchertJpaTutor1PU] Unable to build EntityManagerFactory
javax.persistence.PersistenceException: [PersistenceUnit: SchuchertJpaTutor1PU] Unable to build EntityManagerFactory
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)
        at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
        at entity.PersonTest.initEmfAndEm(PersonTest.java:24)
Caused by: org.hibernate.HibernateException: Could not find datasource
        at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:56)
        at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
        at org.hibernate.ejb.InjectionSettingsFactory.createConnectionProvider(InjectionSettingsFactory.java:29)
        at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:62)
        at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
        at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
        at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:52)

Testcase: emptyTest(entity.PersonTest):        Caused an ERROR
null
java.lang.NullPointerException at entity.PersonTest.cleanup(PersonTest.java:31)
Test entity.PersonTest FAILED

to fix:
- use in memory database in unit tests with persistence.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="SchuchertJpaTutor1TestPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source></non-jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa"/>
        <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        <property name="hibernate.connection.username" value="sa"/>
        <property name="hibernate.connection.password" value=""/>
    </properties>
  </persistence-unit>
</persistence>
- add hsqldb.jar and (possibly) servlet.jar to test libs 

and run the test again, it should pass now..

  • when Address is added to Person, delete the final keyword from getter and setter methods for address.(it results in compile error..)

i will continue with the next tutorial, so see you at the next blog entry :)

29 Haziran 2009 Pazartesi

a sample web based application

i am developping a homework web based application by using the following technologies:
  • apache tomcat 6.0.18, installed with Netbeans 6.5.1
  • toplink (with jpa annotations) for persistence, netbeans automatically creates jpa controller classes
  • jsf, using jsf framework of netbeans, netbeans automatically creates jsf classes and crud pages
  • derby database, coming bundled with netbeans and can be easily managed inside the ide
  • web services, jaxws, using netbeans facilities during development (actually independent from jpa part)
Steps for jpa part:
  1. create a web application with jsf framework added, select tomcat as server runtime.
  2. create a database from databases under services tab. (use that db in the following step) (http://www.netbeans.org/kb/60/ide/java-db.html may help)
  3. create a persistence unit, selecting toplink, the created db in the above step and drop and create as table generation strategy.
  4. create entity classes
  5. generate jsf faces from entity classes
  6. deploy and try from localhost something like that : http://localhost:8084/Registration/faces/welcomeJSF.jsp, do not forget to put faces in the address, that makes the faces servlet deal with that page.
  7. add derbyclient.jar manually (under /opt/sun/javadb/lib in my linux environment ) if you get the following error during run:

Exception [TOPLINK-4003] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Exception Description: Configuration error. Class [org.apache.derby.jdbc.ClientDriver] not found.


and deploy and try again!

my project is working :)

Steps for web service part:

  1. create the web service and deploy again.. if successful, you should see the wsdl at somewhere like that http://localhost:8084/Registration/RegistrationWS?wsdl, generated jpa controller classes can be used within web service operations.
  2. create an other web aplication project. this will be the client that makes use of all deployed web services.
  3. in the client web app, generate the web service client from wsdl.
  4. crate a .jsp file in which you call the web service. this can be done automatically by right clicking in jsp and selecting 'Web Services Client Resources -> Call Web Servicve Operation'
  5. deploy the client web app and test from localhost..

Edit on 20.15 : if you get the following error while generating jsf from entity classes,

Could not find Id property. Be sure the accessor method name matches the variable name.

just move the jpa annotations from variable declarations to accessor methods. That fixed the problem in my case. btw, i faced this problem in Windows Xp, but in OpenSuse everything was fine already..