Announcement Announcement Module
Collapse
No announcement yet.
why does extending @MappedSuperclass remove entity's activeRecord.aj? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • why does extending @MappedSuperclass remove entity's activeRecord.aj?

    I had an entity that wanted to added some common auditing fields to, so I though the best way to achieve thas was to extended a MappedSuperclass, but when I do, the activeRecord.aj of the entity is removed and the tests are all screwed up.

    Here is the entity extending the MappedSuperclass:
    Code:
    @RooJavaBean
    @RooToString
    @RooJpaActiveRecord(identifierColumn = "attachment_id", identifierField = "attachmentId", identifierType = Integer.class)
    public class Attachment extends PersistableObject {
    	
    	@NotNull
    	@Enumerated(EnumType.STRING)
    	@Column(name = "attachment_type")
    	private AttachmentTypeEnum attachmentTypeEnum;
    	
    	@NotNull
    	@Lob @Column(name = "attachment")
    	private byte[] attachmentByteArray;
    	
    	@NotNull
    	@Column(name = "file_name")
    	private String fileName;
    	
    	@NotNull
    	@Column(name = "mime_type")
    	private String mimeType;
    	
    	@ManyToOne
    	@JoinColumn(name = "proposal_id")
    	private Proposal proposal;
    }
    Here is the MappedSuperclass:
    Code:
    @MappedSuperclass
    public abstract class PersistableObject {
    	
    	@Column(name = "added_by", length = 50)
    	private String addedBy;
    }
    All of the Attachment integration tests are broken because Roo removed the Attachment_Roo_Jpa_ActiveRecord.aj file.

    Why? and how can I addthe MappedSuperclass without botching up the entity?

  • #2
    This could be a bug. Would you please raise an issue and attach a zip of your project using the Roo 'backup' command? I would prefer if possible that there are only the two java classes in the project, Attachment and PersistableObject, for simplicity.
    Thanks

    Comment


    • #3
      I just ran across this myself, and found this thread lacking an answer:

      What might work is to change:

      Code:
      @MappedSuperclass
      public abstract class PersistableObject {
      to

      Code:
      @RooJpaActiveRecord(mappedSuperclass = true)
      public abstract class PersistableObject {

      Comment


      • #4
        You're right, this instantly solved the problem and activeRecord.aj files are not removed. Unfortunately this workaround produces some other undesireable behaviour with my integration tests.

        I have an abstract super class with
        Code:
        @RooJpaActiveRecord(mappedSuperclass = true) //@see http://forum.springsource.org/showthread.php?122546-why-does-extending-MappedSuperclass-remove-entity-s-activeRecord-aj
        public abstract class GTBean implements IGTBean { ...

        For this abstract superclass roo produces a fully functional GTBean_Roo_Jpa_ActiveRecord.aj including things like
        Code:
            @Transactional
            public void GTBean.persist() {
                if (this.entityManager == null) this.entityManager = entityManager();
                this.entityManager.persist(this);
            }
            
            @Transactional
            public void GTBean.remove() {
                if (this.entityManager == null) this.entityManager = entityManager();
                if (this.entityManager.contains(this)) {
                    this.entityManager.remove(this);
                } else {
                    GTBean attached = GTBean.findGTBean(this.identifier);  //THIS WILL CAUSE TEST FAILURE IN SUBCLASS INTEGRATION TESTS!!!
                    this.entityManager.remove(attached);
                }
            }
            
            @Transactional
            public void GTBean.flush() {
                if (this.entityManager == null) this.entityManager = entityManager();
                this.entityManager.flush();
            }
            
            @Transactional
            public void GTBean.clear() {
                if (this.entityManager == null) this.entityManager = entityManager();
                this.entityManager.clear();
            }
            
            @Transactional
            public GTBean GTBean.merge() {
                if (this.entityManager == null) this.entityManager = entityManager();
                GTBean merged = this.entityManager.merge(this);
                this.entityManager.flush();
                return merged;
            }
        although this functionality imho clearly belongs to the subclasses' activeRecord concern!!

        When I declare a subclass of the abstract superclass, say
        Code:
        @RooJavaBean
        @RooToString
        @RooJpaActiveRecord(table = Const.TABLE_CONFIGSPACE, persistenceUnit = Const.PERSISTENCE_UNIT, transactionManager = Const.TRANSACTIONMGR)
        public class GTConfigurationSpace extends GTBean implements IGTConfigurationSpace {...
        roo will generate a GTConfigurationSpace_Roo_Jpa_ActiveRecord.aj but will not produce the merge/clear/flush etc. instance methods in it. As a consequence roo produces invalid test code e.g.
        Code:
        @Test
            public void GTConfigurationSpaceIntegrationTest.testRemove() {
                GTConfigurationSpace obj = dod.getRandomGTConfigurationSpace();
                Assert.assertNotNull("Data on demand for 'GTConfigurationSpace' failed to initialize correctly", obj);
                String id = obj.getIdentifier();
                Assert.assertNotNull("Data on demand for 'GTConfigurationSpace' failed to provide an identifier", id);
                obj = GTConfigurationSpace.findGTConfigurationSpace(id);
                obj.remove();  //THIS WILL CALL THE REMOVE-METHOD ON THE MAPPEDSUPERCLASS ACTIVE RECORD CONCERN!!!
                obj.flush(); //THIS WILL CALL THE FLUSH-METHOD ON THE MAPPEDSUPERCLASS ACTIVE RECORD CONCERN!!!
                Assert.assertNull("Failed to remove 'GTConfigurationSpace' with identifier '" + id + "'", GTConfigurationSpace.findGTConfigurationSpace(id));
            }
        However, this makes my integration tests for the subclasses fail because hibernate cannot map GTBean as it is a mapped super class.

        Am I missing something or is this a bug?
        The workaround proposed by John does not work for me. How can I use a mapped super class properly? From my point of view, roo should not create an activeRecord.aj for a mapped super class and should of course not delete activeRecord concerns for all subclasses of a mapped super class.

        Greets, Holger

        Tested on Roo 2.2.1 and 1.3.0.BUILD-SNAPSHOT

        Comment


        • #5
          Hi Holger,

          I see the same generated code in the Roo_Jpa_ActiveRecord.aj for my base class. However, my integration tests don't fail and Hibernate maps all the subclasses just fine in my application.

          In the subclasses I create, I specify:

          Code:
          @RooJavaBean
          @RooToString
          @RooJpaActiveRecord(inheritanceType="SINGLE_TABLE")
          Are you using a different inheritance type?

          The Roo_Jpa_ActiveRecord.aj file for the subclasses define a new method for merge(), since it needs to return an object of the subclass type, but none of the other persistence methods get overridden.

          Comment

          Working...
          X