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