19. März 2009

Hibernate Statistic MBean mit Spring registrieren

Folgender Eintrag muss in die beans.xml:
<bean name="HibernateMBean"
class="com.myorg.mbean.HibernateStatistic"
init-method="init">
<property name="entityManagerFactoryForJMX"
ref="entityManagerFactory" />
</bean>

<bean class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry
key="com.myorg.myapp:Name=HibernateMBean"
value-ref="HibernateMBean">
</entry>
</map>
</property>
</bean>


Die Klasse HibernateStatistic sieht so aus
/**
* Dient der Erzeugung einer HibernateStatistik MBean aus einer JPA EntityManagerFactory. Der Klasse muss eine
* EntityManagerFactory übergeben. Die Klasse selbst kann dann als MBean registriert werden. Sie bietet alle
* Getter/Setter von StatisticsService an. Dann muss die
*
* @author feestra
*
*/
public class HibernateStatistic extends StatisticsService {

/**********************************************************************************************************
* Logger for this class
*/
private static Logger logger = Logger.getLogger(HibernateStatistic.class);
/**********************************************************************************************************
* Wird benötigt für JMX-Hibernate-Statistik.
*/
private EntityManagerFactory entityManagerFactoryForJMX;

private StatisticsService statisticsService;

/**********************************************************************************************************
* Leere Kontruktor. EntityManagerFactory muss über Setter gesetzt werden, dann die init()-Methode
* aufgerufen werden.
*/
public HibernateStatistic() {

}

/**
* EntityManagerFactory über Konstruktor uebergeben, fuehrt dann gleich die init()-Methode auf, um die
* StatisticsService-Instanz zu initialisieren.
*
* @param emf
*/
public HibernateStatistic(EntityManagerFactory emf) {
this.entityManagerFactoryForJMX = emf;
init();
}

public void init() {
EntityManager em = null;
try {

em = getEntityManagerFactoryForJMX().createEntityManager();

StatisticsService statsMBean = new StatisticsService();
Session session = (Session) em.getDelegate();
statsMBean.setSessionFactory(session.getSessionFactory());
statsMBean.setStatisticsEnabled(false);
logger.debug("createHibernateMBeanForJPA was fine.");
statisticsService = statsMBean;

} catch (Exception e) {
logger.error("createHibernateMBeanForJPA failed", e);

} finally {
if (em != null) {
em.close();
}
}
}
...
}

4. März 2009

JPA: Sequences mit Oracle

Problem: Wenn man mit JPA und einer Oracle-Datenbank @GeneratedValue(strategy=GenerationType.SEQUENCE,...) verwendet, werden merkwürdige PKs erzeugt, die nichts mit dem Wert aus der Oracle-Sequence zu tun haben.

Lösung: strategy=GenerationType.SEQUENCE weglassen, da dies intern ein HILO-Verfahren verwendet und nicht jedes Mal die Sequence befragt:

@Id
@GeneratedValue(generator="myseq")
@SequenceGenerator(name="myseq",sequenceName="MY_SEQ")
@Column(name = "PK_MY_TABLE", unique = true, nullable = false, precision = 11, scale = 0)
public long getPkMyTable() {
return this.pkReprData;
}

3. März 2009

JPA/Hibernate sortierte Collections

Problem: Collections einer Entität werden nicht sortiert, obwohl in der Query ein "order by" steht.

Ursache: In der POJO-Klasse ist die Collection als Set definiert.

Lösung: Anstatt des Set einfach eine List verwenden. Die Hibernate Tools generieren leider per Default ein Set.

Dies kann im Build-File z.B. durch folgende zwei Tasks geändert werden:
<replace summary="true" dir="src-orm/com/myorg/dataaccess/orm" token="HashSet" value="ArrayList" />
<replace summary="true" dir="src-orm/com/myorg/dataaccess/orm" token="Set" value="List" />