28 octubre 2009

persistencia y transacciones

http://www.jboss.org/ejb3/docs/reference/build/reference/en/html/hibernate.html#d0e314


5.1. Hibernate Mapping Files

Persistent classes that are mapped using Hibernate .hbm.xml files are supported. The EJB3 Deployer will search the archive for any .hbm.xml files and add them to the definition of the underlying Hibernate SessionFactory. These .hbm.xml files can be virtually anywhere within the archive under any java package or directory.

Class Mappings defined in .hbm.xml files can be managed by EntityManagers just as annotated @Entity beans are. Also, you are allowed to have relationships between a .hbm.xml mapped class and an EJB3 entity. So, mixing/matching is allowed.

5.2. Injection Hibernate Session and SessionFactory

You can inject a org.hibernate.Session and org.hibernate.SessionFactory directly into your EJBs just as you can do with EntityManagers and EntityManagerFactorys. The behavior of a Session is just the same as the behavior of an injected EntityManager. The application server controls the lifecycle of the Session so that you do not have to open, flush, or close the session. Extended persistence contexts also work with injected Hibernate Sessions.

import org.hibernate.Session;
import org.hibernate.SessionFactory;

@Stateful public class MyStatefulBean ... {
@PersistenceContext(unitName="crm") Session session1;
@PersistenceContext(unitName="crm2", type=EXTENDED) Session extendedpc;
@PersistenceUnit(unitName="crm") SessionFactory factory;

}

5.3. Access to org.hibernate.Session

You can get access to the current underlying Hibernate Session by typecasting your reference to EntityManager.

 @PersistenceContext EntityManager entityManager;
public void someMethod();
{
org.jboss.ejb3.entity.HibernateSession hs = (HibernateSession)entityManager;
org.hibernate.Session session = hs.getHibernateSession();
}

5.4. Access to org.hibernate.Query

You can get access to the current underlying Hibernate Query by typecasting your reference to a org.hibernate.ejb.QueryImpl.

 @PersistenceContext EntityManager entityManager;
public void someMethod();
{
javax.persistence.Query query = entityManager.createQuery(...);
org.hiberante.ejb.QueryImpl hs = (QueryImpl)query;
org.hibernate.Query hbQuery = hs.getHibernateQuery();
}


programmatic persistence properties in JPA

JPA also supports programmatic configuration, with a map of options:

Map myProperties = new HashMap();
myProperties.put("hibernate.hbm2ddl.auto", "create-drop");
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("helloworld", myProperties)

Custom programmatic properties override any property you’ve set in the persis-
tence.xml configuration file.

persistencia y transacciones

otra forma de establecer los boundaries de una transacción en JPA:

package hello;
import java.util.*;
import javax.persistence.*;
public class HelloWorld {
public static void main(String[] args) {
// Start EntityManagerFactory
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("helloworld");
// First unit of work
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Message message = new Message("Hello World");
em.persist(message);
tx.commit();
em.close();
// Second unit of work
EntityManager newEm = emf.createEntityManager();
EntityTransaction newTx = newEm.getTransaction();
newTx.begin();
List messages = newEm
.createQuery("select m from Message m
➥ order by m.text asc")
.getResultList();

System.out.println( messages.size() + " message(s) found" );
for (Object m : messages) {
Message loadedMsg = (Message) m;
System.out.println(loadedMsg.getText());
}
newTx.commit();
newEm.close();
// Shutting down the application
emf.close();
}
}

persistencia y transacciones

These are your primary programming interfaces in Java Persistence:

■ javax.persistence.Persistence—A startup class that provides a static method for the creation of an EntityManagerFactory.

■ javax.persistence.EntityManagerFactory—The equivalent to a Hibernate SessionFactory. This runtime object represents a particular persistence unit. It’s thread-safe, is usually handled as a singleton, and provides methods for the creation of EntityManager instances.

■ javax.persistence.EntityManager—The equivalent to a Hibernate Session. This single-threaded, nonshared object represents a particular unit of work for data access. It provides methods to manage the lifecycle of entity instances and to create Query instances.

■ javax.persistence.Query—This is the equivalent to a Hibernate Query.
An object is a particular JPA query language or native SQL query representation, and it allows safe binding of parameters and provides various methods for the execution of the query.

javax.persistence.EntityTransaction—This is the equivalent to a Hibernate Transaction, used in Java SE environments for the demarcation of RESOURCE_LOCAL transactions. In Java EE, you rely on the standardized javax.transaction.UserTransaction interface of JTA for programmatic transaction demarcation.

persistencia y transacciones

otra forma de establecer los boundaries de la transacción:


package hello;
import java.util.*;
import org.hibernate.*;
import persistence.*;
public class HelloWorld {
public static void main(String[] args) {
// First unit of work
Session session =
HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Message message = new Message("Hello World");
Long msgId = (Long) session.save(message);
tx.commit();
session.close();
// Second unit of work
Session newSession =
HibernateUtil.getSessionFactory().openSession();
Transaction newTransaction = newSession.beginTransaction();
List messages =
newSession.createQuery("from Message m order by
➥ m.text asc").list();
System.out.println( messages.size() +
" message(s) found:" );
for ( Iterator iter = messages.iterator();
iter.hasNext(); ) {
Message loadedMsg = (Message) iter.next();
System.out.println( loadedMsg.getText() );
}
newTransaction.commit();
newSession.close();
// Shutting down the application
HibernateUtil.shutdown();
}
}


sacado del chapter2.pdf del libro de hibernate (pag.47)

Test: trucos para acceder a recursos en los test

(sacado del ejemplo de hibernate caveatemptor-jpa-061211)

testsuite-integration-ejb3.xml:
<!-- DBUnit needs a database connection -->
<parameter name="jndi_datasource" value="java:/caveatemptorTestingDatasource">

<!-- How do we get an EntityManagerFactory from JNDI in tests? -->
<parameter name="jndi_name_emf" value="java:/EntityManagerFactories/caveatEmptorEMF">

<!-- How do we get a JTA UserTransaction from JNDI in tests? -->
<parameter name="jndi_name_usertx" value="UserTransaction">

HIBERNATE: Para que solamente detecte las anotaciones

En el persistence.xml:

<!-- Only scan and detect annotated entities -->
<property name="hibernate.archive.autodetection" value="class">


(sacado del ejemplo de hibernate caveatemptor)

18 octubre 2009

Hibernate - Cascade recommendations

Recommendations:

  • It doesn't usually make sense to enable cascade on a @ManyToOne or @ManyToMany association. Cascade is often useful for @OneToOne and @OneToMany associations.

  • If the child object's lifespan is bounded by the lifespan of the parent object, make the parent a full lifecycle object by specifying CascadeType.ALL and org.hibernate.annotations.CascadeType.DELETE_ORPHAN (please refer to the Hibernate reference guide for the semantics of orphan delete)

  • Otherwise, you might not need cascade at all. But if you think that you will often be working with the parent and children together in the same transaction, and you want to save yourself some typing, consider using cascade={PERSIST, MERGE}. These options can even make sense for a many-to-many association.

Hibernate - Query Hints

3.4.1.7. Query hints


Query hints (for performance optimization, usually) are implementation specific. Hints are declared using the query.setHint(String name, Object value) method, or through the @Named(Native)Query(hints) annotation Note that these are not SQL query hints! The Hibernate EJB3 implementation offers the following query hints:

Table 3.1. Hibernate query hints

HintDescription
org.hibernate.timeoutQuery timeout in seconds ( eg. new Integer(10) )
org.hibernate.fetchSizeNumber of rows fetched by the JDBC driver per roundtrip ( eg. new Integer(50) )
org.hibernate.commentAdd a comment to the SQL query, useful for the DBA ( e.g. new String("fetch all orders in 1 statement") )
org.hibernate.cacheableWhether or not a query is cacheable ( eg. new Boolean(true) ), defaults to false
org.hibernate.cacheModeOverride the cache mode for this query ( eg. CacheMode.REFRESH )
org.hibernate.cacheRegionCache region of this query ( eg. new String("regionName") )
org.hibernate.readOnlyEntities retrieved by this query will be loaded in a read-only mode where Hibernate will never dirty-check them or make changes persistent ( eg. new Boolean(true) ), default to false
org.hibernate.flushModeFlush mode used for this query
org.hibernate.cacheModeCache mode used for this query

The value object accept both the native type or its string equivalent (eg. CaheMode.REFRESH or “REFRESH”). Please refer to the Hibernate reference documentation for more information.