4

I have an abstract root class, let's say A.

And I have several implementation classes extending A.

A has FIELD annotation as well as some @XmlElement annotated properties.

A also has an abstract method.

When marshalling (B extends A), the value returned by the abstract method gets marshalled as attribute. Not as expected, right?

@XmlAccessorType(XmlAccessType.FIELD)
public abstract class SpecialProfile extends ContentNodeBean {

  @XmlElement(name="do-index", namespace="my")
  private boolean doIndex = false;

  public abstract SpecialProfileType getSpecialProfileType();

  ... getters and setters for properties ...   
}

Does anybody have the same issue and how can this be fixed?

I am using org.eclipse.persistence.moxy 2.1.2

bdoughan
  • 147,609
  • 23
  • 300
  • 400
basZero
  • 4,129
  • 9
  • 51
  • 89

1 Answers1

1

I am attempting to reproduce your issue, but so far have been unsuccessful. Can you see where I'm doing something different than you are? The following is my sample code:

A

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public abstract class A {

    public abstract C getC();
    public abstract void setC(C c);

}

B

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class B extends A {

    private C c;

    @Override
    public C getC() {
        return c;
    }

    @Override
    public void setC(C c) {
        this.c = c;
    }

}

C

public class C {

}

Demo

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import org.eclipse.persistence.Version;

public class Demo {

    public static void main(String[] args) throws Exception {
        System.out.println(Version.getVersionString());

        JAXBContext jc = JAXBContext.newInstance(B.class);
        System.out.println(jc);

        B b = new B();
        b.setC(new C());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(b,System.out);
    }

}

Output

2.1.2.v20101206-r8635
org.eclipse.persistence.jaxb.JAXBContext@100ab23
<?xml version="1.0" encoding="UTF-8"?>
<b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="b"><c/></b>

UPDATE

Based on your comments:

  • B does not inherit A's XmlAccessorType settings.
  • It is not the abstract method that you need to mark @XmlTransient, but the field used to implement the accessor on the B class.

The following is what class B should look like:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class B extends A {

    @XmlTransient
    private C c;

    @Override
    public C getC() {
        return c;
    }

    @Override
    public void setC(C c) {
        this.c = c;
    }

}
bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • Hi, looking at your Output, the gets marshalled although c should not get marshalled, right? There is no field annotation. What I am expecting is that C does NOT get marshalled... – basZero Feb 24 '11 at 16:33
  • Also: is B inheriting the @XmlAccessorType(XmlAccessType.FIELD) annotation from A? I have set that annotation in B too, just to be sure. – basZero Feb 24 '11 at 16:34
  • and also: I have tried the @XmlTransient annotation on the abstract methods in class A, it is still marshalling it. – basZero Feb 24 '11 at 16:36
  • Ok, this I understand, but in my case there is no property c that I could annotate. The object is created on the fly. Is this maybe the problem? – basZero Feb 24 '11 at 17:15
  • Created on the fly, as in using ASM to generate the class programatically? – bdoughan Feb 24 '11 at 17:27