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.

09 octubre 2009

teresa forcades - confabulación gripe A

El afán de protagonismo de la religiosa Teresa Forcades la lleva a fomentar el alarmismo sobre la Gripe A

Una reflexión y una propuesta en relación a la nueva gripe


When a pandemic isn't a pandemic


Extraits du corriel

27 septiembre 2009

Deploying custom resources

creamos un nuevo action:

public void action1_(){
ResourceBundle bundle = SeamResourceBundle.getBundle();
String sql = bundle.getString("sql1");

log.info("sql: " + sql);
statusMessages.add("sql: " + sql);
}

y ponemos el sql.properties en el directorio src/hot:

sql1=select h from Hotel h where h.name like '%#{exampleHotel.name}%'







from http://seamframework.org/Community/IncludingAResourceBundleNotCalledMessages


<core:resource-loader>
<core:bundle-names>
<value>mycompany_messages</value>
</core:bundle-names>
</core:resource-loader>




from seam reference 2.1.1-GA.pdf


29.10. Deploying custom resources (externalizar SQL's)


Se trata de crear un componente que se cargue en el arranque de la aplicación, y contenga un set de properties con las sql's de la aplicación, y que se pueda desplegar en caliente por si se actualiza el fichero de properties.

21 septiembre 2009

24.2.1. Using the Hibernate API

24.2.1. Using the Hibernate API

To use the Hibernate API to manage the database objects, we inject a Hibernate Session in-
stead of an EntityManager into the ManagerPojo class. The API methods in the Hibernate
Session is roughly equivalent to methods in the EntityManager; they have only slightly dif-
ferent method names. This is the Hibernate version of the ManagerPojo class:

@Name("manager")
@Scope (APPLICATION)
public class ManagerPojo {
@In (required=false) @Out (required=false)
private Person person;
@In (create=true)
private Session helloSession;
Long pid;
@DataModel
private List fans;
@DataModelSelection
private Person selectedFan;
public String sayHello () {
helloSession.save (person);
return "fans";
}
@Factory("fans")
public void findFans () {
fans = helloSession.createQuery(
"select p from Person p")
.list();
}
public void setPid (Long pid) {
this.pid = pid;
if (pid != null) {
person = (Person)
helloSession.get(Person.class, pid);
} else {
person = new Person ();
}
}
public Long getPid () {
return pid;
}
public String delete () {
Person toDelete =
(Person) helloSession.merge (selectedFan);
helloSession.delete( toDelete );
findFans ();
return null;
}
public String update () {
return "fans";
}
}

Display Error Messages on the Web Form

10.4. Display Error Messages on the Web Form



s:decorate>
f:facet name="beforeInvalidField">
h:graphicimage src="anotherError.gif">
/h:graphicimage>
f:facet name="afterInvalidField">
s:message styleclass="anotherError">
/s:message>
f:facet name="aroundInvalidField">
s:span styleclass="error">
/s:span>
h:inputtext value="#{person.name}">
/h:inputtext>/f:facet>/f:facet>/f:facet>/s:decorate>

exception management in pages.xml

14.4., “Use pages.xml for System
Exceptions”



from booking example:



pages.xml


You must be logged in to use this feature





Session expired, please log in again

Annotate exceptios

From the book 'JBoss Seam Simplicity and Power Beyond Java EE':

14.3 Annotate Exceptions

@ApplicationException(rollback=true)
@Redirect(viewId="/inventoryError.xhtml")
public class InventoryException
extends Exception {
public InventoryException () { }
}
14.4. Use pages.xml for System Exceptions

SVN hooks for hudson builds

En el directorio hooks del repositorio renombramos/copiamos post-commit.bat (o .exe)

en el fichero post-commit.bat escribimos:

python C:\svnrepos\notify_hudson.py




escribir este script en un fichero llamado notify_hudson.py:


import urllib, urllib2, time

url = 'http://localhost:8080/hudson/job/seam4hudson/build?token=build&cause=svncommit+texto'

values = {'token' : 'build', #write ur specific key/value pair
'key2' : 'value2',
'key3' : 'value3',
}

try:
# data = urllib.urlencode(values)
req = urllib2.Request(url)
response = urllib2.urlopen(req)
the_page = response.read()
print the_page
except Exception, detail:
print "Err ", detail




script sacado de http://love-python.blogspot.com/2008/04/get-content-html-source-of-url-by-http.html

24 julio 2009

maven release version plugin

Para modificar las versiones de los pom.xml y sus hijos:

=======

http://stackoverflow.com/questions/415764/hierarchy-of-maven-projects-without-scattering-the-version-number
I think this approach can be complemented with Maven version plug-in: mojo.codehaus.org/versions-maven-plugin It can increment the parent.version tag in child projects automatically; see versions:update-child-modules goal. – Dan May 13 at 16:38


=======

Versions Maven Plugin




=======

Maven Release Plugin


=======

09 julio 2009

Taylor 1.3.0 - Writing Custom Generators


Writing Custom Generators

From Taylor

Taylor MDA comes with a set of code generation templates. But you may want to write your own templates for any number of reasons:

  • You want to use a different language: Ruby, PHP, .Net, etc
  • You want to use a different framework: Seam vs Spring, JSF vs GWT, etc
  • You simply want the code to generate different
  • Etc...

If you just want to fix a bug you can override a template: Customize Code Templates

The following outlines how to create your own code generator plugin. These are sometime called cartridges.

Contents

[hide]

Plugin Basics

For starters, code generators are just Eclipse plugins, so here is a good primer:

Create Plugin

  1. Start by creating a basic plugin project.
    1. Copy net.taylor.mda.samplegen to get a jump start.
  2. Modify the MANIFEST.MF to match the project name, package and version.
  3. Modify the PLUGIN_ID in the GeneratorPlugin class.
  4. Build the plugin

Here is the basic layout of a plugin:

  • project
    • src
      • net.taylor.mda.mygen.GeneratorPlugin
      • net.taylor.mda.generator.template.*
    • templates
      • main
        • java
        • resources
      • maven
      • test
        • java
        • resources
      • Header.jetinc
    • META-INF
      • MANIFEST.MF
    • plugin.xml
    • build.properties
    • .jetproperties
    • .classpath
    • .project

NOTE: By convention the template directory mimics the structure of the generated code. For example, src/main/java, src/main/resources, src/test/java, src/test/resources

Create Template

If you are new to JET, you will want to review and refer back to these tutorials:

The sample generator plugin contains a sample template.

Use the JET editor (included with taylor) to test the sample template

  • You will need to register it with *.*jet extensions

Here are the highlights of a template:

  • Name template files with an informational extensions such as: *.javajet, *.xmljet, *.xhtmljet
  • The first line of the template defines the class name and the imports.
  • The second line defines the type of UML element that is passed as an argument to the template.
<%@ jet package="net.taylor.mda.generator.template.main.java.sample" class="SampleGen"
imports="org.eclipse.uml2.uml.* java.util.* net.taylor.mda.generator.util.* org.eclipse.emf.codegen.util.*"
%>
<%Model uml2Package = (Model) argument;%>
  • This code handles formatting imports for java code. Imports are adding implicitly based on the UML model. Framework imports are added explicitly as shown below.
<%ImportManager importManager=null;%>
<%if (NameHelper.getQualifiedName(uml2Package) != null) {%>
<%importManager = ImportHelper.makeImportManager(NameHelper.getQualifiedName(uml2Package));%>
<%} else {%>
<%importManager = ImportHelper.makeImportManager("");%>
<%}%>
<%importManager.addImport("java.io.Serializable");%>
<%importManager.addImport("org.jboss.seam.ScopeType");%>
<%importManager.addImport("org.jboss.seam.annotations.Logger");%>
<%importManager.addImport("org.jboss.seam.annotations.Name");%>
<%importManager.addImport("org.jboss.seam.annotations.Observer");%>
<%importManager.addImport("org.jboss.seam.annotations.Scope");%>
<%importManager.addImport("org.jboss.seam.log.Log");%>

<%
StringBuffer importStringBuffer = stringBuffer;
int importInsertionPoint = stringBuffer.length();
importManager.addCompilationUnitImports(stringBuffer.toString());
%>

...

<%importStringBuffer.insert(importInsertionPoint, importManager.computeSortedImports());%>

  • This block shows an example of generating java code.
  • Various helper classes are available in package net.taylor.mda.generator.util.
<%@ include file="../../Header.jetinc"%>
package <%=NameHelper.getQualifiedName(uml2Package)%>;

...

/**
* <%=TypeHelper.getDocumentation(uml2Package)%>
*
* @author <%=System.getProperty("user.name")%>
* @generated
*/
@Name("<%=NameHelper.getUncapName(uml2Package)%>Init")
@Scope(ScopeType.APPLICATION)
public class <%=NameHelper.getCapName(uml2Package)%>Init implements Serializable {

/** @generated */
@Logger
private Log log;

/** @generated */
@Observer("org.jboss.seam.postInitialization")
public void init() throws Exception {
log.info("Starting <%=NameHelper.getCapName(uml2Package)%>Init...");
}
}

Register Template

This is the part that is uniquely Taylor.

Each template is registered in its plugin.xml file using the template extension point. The engine in the Generator plugin uses these extensions to determine which templates to execute and how to render the menus.

                  id="EntityClass"
path="/main/java/entity/EntityClass.javajet"
outputPattern="/src/main/java/{0}/{1}.java"
ifExists="merge"
projectSuffix="jpa"
hasStereotype="javax.persistence.Entity"
modelElement="org.eclipse.uml2.uml.internal.impl.ClassImpl">


  • id - a unique name that will be used to reference this template
  • path - the relative location and name of the template
  • modelElement - what UML type does the template apply to
  • hasStereotype - further restrict matches based on an applied stereotype
  • outputPattern - describes the generated file name and path with substitutions
    • {0} - path based on UML Package
    • {1} - name of UML element
    • {2} - name of parent UML element
    • {3} - fully qualified UML element name with '::' replaced with '-'
    • {4} - lower case model name with '_' replaced with '.'
    • {5} - model name with '_' replaced with '.'
  • ifExists - what to do if the file already exists: merge, skip, backup
  • projectSuffix - files are generated in project named -, a new project is created if it doesn't exist


See the existing template plugins as examples.

Test Template

We already used the JET Editor preview tab to unit test a template. Now we need to test that the template is properly registered.

  1. Run the plug-in project as an Eclipse Application from the tool bar.
  2. Create a test model
  3. Test the Generate menu to verify that you template appears (see Generate Code)
  4. Now Generate and validate the results
  • You will likely want to install the EMF and UML2 SDKs for debugging.
  • The Engine will also log exceptions to the console.
  • Plugging errors will show up in the Eclipse Error Log view.

That is basically it!

The following are some optional topics.

Profiles

Taylor comes with many profiles. However, you may want to create your own for a specific framework or specification.

If you are new to UML Profiles, you will want to review and refer back to this tutorial:

You can reverse engineer a profile from a jar that contains annotations.

  • File > Import > Taylor > Import Java Annotations to UML Profile

Package the profile in a plug-in, such as the one with the templates.

Adding the following extensions to the plugin.xml will automatically add the profile to any new models.

  
source="pathmap://MY_PROFILES/"
target="platform:/plugin/my.plugin.profiles/profiles/">




id="pathmap://MY_PROFILES/my.profile.uml"/>

See plug-in net.taylor.mda.profiles for examples.

Utility Actions

You often need to make mass changes to a model such as spinning through all the elements and adding various stereotypes. This saves time and improves consistency.

This is accomplished using the standard Eclipse action menu mechanism. Package these actions in a plugin along side your templates and profiles.

See the net.taylor.mda.jpagen plug-in for examples.

The following example shows how to register the utilities in a plugin.xml file to be applied to a particular type of UML element.

           point="org.eclipse.ui.navigator.viewer">
viewerId="net.taylor.mda.ModelNavigator">






point="org.eclipse.ui.navigator.navigatorContent">
id="net.taylor.mda.jpagen.actions.AddEnumerationAction"
class="net.taylor.mda.jpagen.actions.AddEnumerationActionExtension">







Taylor 1.3.0-building the plugins

Taylor 1.3.0

Building the plugins


Building the Plug-ins

  1. Start by creating a dedicated workspace.
  2. Then checkout the plug-ins from SVN.
  3. To build the plug-ins right-click on the net.taylor.mda project and select Export>Plug-in Development>Deployable features
  4. Specify a Destination Directory, such as C:\workspaces\build, and press Finish
  5. Copy the features and plugins directories from your build directory to your eclipse directory
  6. Restart Eclipse with the -clean option

Testing the Plug-ins

  1. Follow the steps above to checkout the plug-in projects
  2. Select the net.taylor.mda project
  3. Go to Run>Run As>Eclipse Application or Run>Debug As>Eclipse Application

Optional

  • Install the SDKs for GMF and its dependencies for debugging