Results 1 to 5 of 5

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

  1. #1
    Join Date
    Apr 2006
    Posts
    23

    Default 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. #2
    Join Date
    Dec 2005
    Posts
    935

    Default

    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
    Alan Stewart
    Spring Roo Committer
    twitter @alankstewart

  3. #3
    Join Date
    May 2011
    Posts
    9

    Default

    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 {

  4. #4
    Join Date
    Mar 2011
    Posts
    4

    Default

    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

  5. #5
    Join Date
    May 2011
    Posts
    9

    Default

    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •