Announcement Announcement Module
No announcement yet.
Using a BaseObject in Roo JPA with Hibernate Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using a BaseObject in Roo JPA with Hibernate

    In Hibernate MySQL webapps (non-Roo) I've done before I have been able to use a BaseObject class to handle common behavior such as maintaining chicken-tracks properties (initial add date/user/location, last modified date/user/location).

    It seems that using AspectJ might be a more Roo-like way of doing this, but now was not the time for me to go down that path. I also looked at a add-on that just handled date added/modified - but I needed to do a bit more.

    Anyway I have tried every which way with Roo 1.2.3 using JPA and Hibernate. the only way I got it to work was using a base object like the one below, with the following subclass. The problem was that it uses a single sequence to assign id numbers across all subclasses, not a separate sequence per subclass. For some situations that might not matter, but in my case it does.

    I've also tried removing all annotations from the BaseObject class - I really don't ever need to treat anything (queries, etc) as a BaseObject. But that does not work either - it prevents Roo from generating the .aj files that provide the EntityManager.

    Is there anyway to get this to work?

    Thanks - Richard

    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class BaseObject implements Comparable {
        private Date addedOn;
        private Date modifiedOn;
        private String addedBy;
        private String modifiedBy;
        private String addedFrom;
        private String modifiedFrom;
        public BaseObject() {
        public void onPersist() {
            log.debug("before=" + this.string());
            this.modifiedOn = new Date();
            ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest req = (sra == null) ? null : sra.getRequest();
            if (req != null) {
                this.modifiedBy = (req.getRemoteUser() == null) ? "BATCH" : req.getRemoteUser();
                this.modifiedFrom = (req.getRemoteAddr() == null) ? "" : req.getRemoteAddr();
            } else {
                this.modifiedBy = "BATCH";
                this.modifiedFrom = "";
            this.addedOn = (this.addedOn == null) ? this.modifiedOn : this.addedOn;
            this.addedBy = (this.addedBy == null) ? this.modifiedBy : this.addedBy;
            this.addedFrom = (this.addedFrom == null) ? this.modifiedFrom : this.addedFrom;
            log.debug(" after=" + this.string());
    Subclass 1
    @RooJpaActiveRecord(finders = { "findNotesByNameEquals" })
    public class Note extends BaseObject {
        @Column(unique = true)
        @Size(min = 2, max = 30)
        private String name;
        @Size(min = 0, max = 4096)
        private String text;
    Subclass 2
    @RooJpaActiveRecord(finders = { "findOrganizationsByOrgIdEquals", "findOrganizationsByEnabledAsCustomer", "findOrganizationsByEnabledAsChannelPartner", "findOrganizationsByOrgIdLike", "findOrganizationsByOrgIdEqualsAndEnabledAsCustomer", "findOrganizationsByOrgIdLikeAndEnabledAsCustomer" })
    public class Organization extends BaseObject {
        @Column(unique = true)
        @Size(min = 2, max = 30)
        private String orgId;
        @Column(unique = true)
        @Size(min = 2, max = 48)
        private String orgName;
        private boolean enabledAsCustomer;
        private boolean enabledAsChannelPartner;
        public Organization() {

  • #2
    One Possible Solution

    Using a mappedSuperclass for BaseObject will help to generate separate id sequences.

    The fields from the mappedSuperclass, BaseObject in this case, will be inherited by Organization and Note.

    Tables are generated for Organization and Note, but BaseObject would not be mapped to any table.

    As far as I'm aware, if BaseObject was annotated as a mappedSuperclass, then it wouldn't be able to participate in any relationships, since it is not an @Entity or @Persistent type. This doesn't relate to your question, but I thought I would mention it anyway.

    You could try something like:

    entity jpa --class ~.BaseObject --mappedSuperclass --inheritanceType TABLE_PER_CLASS
    field date --fieldName addedOn --type java.util.Date
    field date --fieldName modifiedOn --type java.util.Date
    field string --fieldName addedBy
    field string --fieldName modifiedBy
    field string --fieldName addedFrom
    field string --fieldName modifiedFrom
    entity jpa --class ~.Note --extends ~.BaseObject --activeRecord
    field string --fieldName name --sizeMin 2 --sizeMax 30 --unique --notNull 
    field string --fieldName text --sizeMin 0 --sizeMax 4096
    entity jpa --class ~.Organization --extends ~.BaseObject --activeRecord 
    field string --fieldName orgId --sizeMin 2 --sizeMax 30 --unique --notNull 
    field string --fieldName orgName --sizeMin 2 --sizeMax 48 --unique --notNull 
    field boolean --fieldName enabledAsCustomer --assertTrue
    field boolean --fieldName enabledAsChannelPartner --assertTrue
    I'm not too sure what you're using the orgId field for; perhaps for manual entry or third-party reference?

    When this is run and two records are entered, one for an Organization and one for a Note, then each row in their respective tables will have their own ID values. In other words, for the very first two records, the ID will be 1 for both the Organization and the Note.

    I hope this is some help.
    Last edited by Wayne Riesterer; Aug 4th, 2013, 07:51 PM. Reason: Added --activeRecord to Note and wrapped roo code in CODE tags.