0 Replies Latest reply on Mar 10, 2009 1:26 PM by fcousin

    How to deal with application Framework and entity inheritance

    fcousin

      Hello,


      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