How to deal with application Framework and entity inheritance
fcousin Mar 10, 2009 1:26 PMHello,
Because I searched a lot, and I am happy to have found it, I want to share my code (even if it is just 'test code', so not very pretty). The Seam version is 2.11.GA.
In my application, I have an class 'Activite' (Activity). This class has two child : 'Production' and 'Inactivite' (Inactivity).
First, I have managed to deal with inheritance and EntityHome (the code is above), in SINGLE_TABLE mode.
I first code the classes, then generated whith seam-gen, then updated the pages (ProductionEdit.xhtml and ActiviteEdit.xhtml). I could edit one of 'Production' or 'Inactivite', with informations from their parent class (the two dates).
The table generated looks so :
agora-01=# \d activite Table "public.activite" Column | Type | Modifiers -------------+-----------------------------+----------- activite_id | integer | not null date_debut | timestamp without time zone | date_fin | timestamp without time zone | version | integer | type | integer | descriptif | character varying(255) | libelle | character varying(255) | role | character varying(255) | Indexes: "activite_pkey" PRIMARY KEY, btree (activite_id)
The orders generated in my database looks like this (extract from my Postgresql database log) :
2009-03-10 10:08:22 CET LOG: execute <unnamed>: update activite set date_debut=$1, date_fin=$2, version=$3, descriptif=$4, libelle=$5, role=$6 where activite_id=$7 2009-03-10 10:08:22 CET DETAIL: parameters: $1 = '2009-03-02 00:00:00', $2 = '2009-03-03 00:00:00', $3 = NULL, $4 = 'data', $5 = 'data', $6 = 'zzzz', $7 = '254'
That's fine! I hope this could help someone else (I found some questions, but no answer in the forum).
Here is the code for the SINGLE_TABLE version :
First, the abstract class :
Activite.java
package com.sopra.academy.seam.agora.entity; import java.util.Date; import javax.persistence.Column;
(imports...)
import org.hibernate.validator.NotNull;
import org.jboss.seam.annotations.Name;
/*
* Classe pour gestion de l'activité des collaborateurs
*/
@Entity
@Table(name = "activite")
@Inheritance(
strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.INTEGER)
public abstract class Activite implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // identifiant primaire
private Integer version;
private Date date_debut;
private Date date_fin;
@Column(name = "activite_id", nullable = false, unique = true)
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "activite_seq")
@SequenceGenerator(name = "activite_seq", sequenceName = "activite_seq")
@NotNull
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Version
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
/**
* @return the date_debut
*/
public Date getDate_debut() {
return date_debut;then getters and setters...
Production.java :
package com.sopra.academy.seam.agora.entity;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import org.jboss.seam.annotations.Name;
@Entity
@Name("production")
@DiscriminatorValue("1") //le type pour une activité production est 1
public class Production extends Activite{
private String libelle;
private String descriptif;
private String role;
/**
* @return the libelle
*/
public String getLibelle() {
return libelle;(and other getter/setter)
The ProductionEdit.xhtml page (extract)
(this is the page generated by seam-gen, plus the fields date_debut and date_fin.)
<h:form id="production" styleClass="edit">
<rich:panel>
<f:facet name="header">#{productionHome.managed ? 'Edit' : 'Add'} Production</f:facet>
<s:decorate id="libelleField" template="layout/edit.xhtml">
<ui:define name="label">Libelle</ui:define>
<h:inputTextarea id="libelle"
cols="80"
rows="3"
value="#{productionHome.instance.libelle}"/>
</s:decorate>
<s:decorate id="date_debutField" template="layout/edit.xhtml">
<ui:define name="label">Date_debut</ui:define>
<rich:calendar id="date_debut"
value="#{productionHome.instance.date_debut}" datePattern="MM/dd/yyyy" />
</s:decorate>
<s:decorate id="date_finField" template="layout/edit.xhtml">
<ui:define name="label">Date_fin</ui:define>
<rich:calendar id="date_fin"
value="#{productionHome.instance.date_fin}" datePattern="MM/dd/yyyy" />
</s:decorate>
<s:decorate id="roleField" template="layout/edit.xhtml">
<ui:define name="label">Role</ui:define>
<h:inputTextarea id="role"
cols="80"
rows="3"
value="#{productionHome.instance.role}"/>
</s:decorate>
But, in fact, I wanted to implement JOINED inheritance.
So, I transformed the :
@Inheritance(
strategy=InheritanceType.SINGLE_TABLE)
into :
@Inheritance(
strategy=InheritanceType.JOINED)
Then, it ignores the discriminator (it seems normal to me, so I think one can remove it...)
Three tables are created, with an foreign key from each child to the parent table.
And the insertion orders look like these :
2009-03-10 11:57:32 CET LOG: execute <unnamed>: insert into activite (date_debut, date_fin, version, activite_id) values ($1, $2, $3, $4) 2009-03-10 11:57:32 CET DETAIL: parameters: $1 = '2009-03-11 00:00:00', $2 = '2009-03-25 00:00:00', $3 = NULL, $4 = '450' 2009-03-10 11:57:32 CET LOG: execute <unnamed>: insert into Production (descriptif, libelle, role, activite_id) values ($1, $2, $3, $4) 2009-03-10 11:57:32 CET DETAIL: parameters: $1 = 'e', $2 = 'e', $3 = 'eee', $4 = '450'
That is fine, too.
Now, I only have a problem with this :
<rich:calendar id="date_debut"
value="#{productionHome.instance.date_debut}" datePattern="MM/dd/yyyy" />Because I do not know how to update the field 'date_debut' without the 'rich'. I tried with an h:inputTextarea but the updates are ignored...
If there is any problem here, of if you have comments, please let me know.
Flo