微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 使用JAXB将子类实例作为超类传递

我有一组代表消息类型的 Java类(接近25).他们都是继承自我想抽象的Message类.每个消息类型为Message超类提供的集合添加了一些附加字段.

我正在使用RESTeasy实现一些RESTful Web服务,并希望有这样的方法

public Response persist(Message msg) {
    EntityTransaction tx = em.getTransaction();
    tx.begin();
    try {
        em.persist(msg);
    } catch (Exception e) {
        e.printstacktrace();
    }
    tx.commit();
    em.close();
    return Response.created(URI.create("/message/" + msg.getId())).build();
}

而不是使用25个单独的持久化方法

目前,我已经注释了我的Message类,如下所示:

@MappedSuperclass
@XmlRootElement(name = "message")
public abstract class Message implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Integer id;
    @Embedded
    Header header;
    @Embedded
    SubHeader subHeader;

我的子类看起来像这样:

@Entity
@XmlRootElement(name="regmessage")
@XmlAccessorType(XmlAccesstype.FIELD)
public class REGMessage extends Message {

    @XmlElement(required = true)
    int statusUpdaterate;
    @XmlElement(required = true)
    int networkRegistrationFlag;

这将创建一个看起来像应该工作的模式,但是在持久化操作期间在服务器端看到的所有模式都是一个Message对象(子类型完全丢失,或者至少没有被编组回到其正确的子类型).在客户端,调用方法我这样做:

REGMessage msg = new REGMessage();
// populate its fields
Response r = client.createMessage(msg);

是我试图可能的吗我需要使用什么JAXB魔术来使翻译发生在他们应该的方式 – 即,将Java中的所有内容视为消息,以保持方法数量仍然保留所有子类型特定信息?

感谢Blaise的博客指南,现在看起来正在全面的工作.这是我已经得到的,它的工作:

//JAXB annotations
@XmlRootElement(name="message")
@XmlAccessorType(XmlAccesstype.FIELD)
@XmlSeeAlso(REGMessage.class)
//JPA annotations
@MappedSuperclass
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @XmlAttribute
    private Integer id;

    private JICDHeader header;
    private int subheader;

    @XmlAnyElement
    @Transient
    private Object body;

我今天早上遇到的一个问题是Hibernate关于列数不匹配的一个隐含的错误.一旦我意识到“身体”正在映射到表中,我标记为短暂的,瞧!

@XmlRootElement(name="regmessage")
@XmlAccessorType(XmlAccesstype.FIELD)
@Entity
public class REGMessage extends Message {

    private int field1;
    private int field2;

现在,该代码生成的唯一表是regmessage表.在RESTeasy方面:

@Path("/messages")
public class MessageResource implements IMessageResource {

    private EntityManagerFactory emf;
    private EntityManager em;

    Logger logger = LoggerFactory.getLogger(MessageResource.class);

    public MessageResource() {
        try {
            emf = Persistence.createEntityManagerFactory("shepherd");
            em = emf.createEntityManager();
        } catch (Exception e) {
            e.printstacktrace();
        }
    }

    @Override
    @POST
    @Consumes("application/xml")
    public Response saveMessage(Message msg) {

        System.out.println(msg.toString());

        logger.info("starting saveMessage");
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            em.persist(msg);
        } catch (Exception e) {
            e.printstacktrace();
        }

        tx.commit();
        em.close();
        logger.info("ending saveMessage");

        return Response.created(URI.create("/message/" + msg.getId())).build();
    }
}

这实现了一个接口:

@Path("/messages")
public interface IMessageResource {

    @GET
    @Produces("application/xml")
    @Path("{id}")
    public Message getMessage(@PathParam("id") int id);

    @POST
    @Consumes("application/xml")
    public Response saveMessage(Message msg) throws URISyntaxException;

}

编组&解组工作按预期,持久性是子类的表(根本没有超类表).

我确实看到了Blaise关于JTA的笔记,我可以尝试在完成“Message& REGMessage类完全退出.

解决方法

您是否尝试将以下内容添加到消息类中? @XmlSeeAlso注释将让JAXBContext知道子类.
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;

@XmlRootElement
@XmlSeeAlso(RegMessage.class)
public abstract class Message {

    Integer id;

}

替代策略:

这是我帮助人们使用的策略的链接

> http://bdoughan.blogspot.com/2010/08/using-xmlanyelement-to-build-generic.html

本质上你有一个消息对象和多个单独的消息有效载荷.消息和有效负载间的关系通过@XmlAnyElement注释来处理.

交易处理说明

我注意到你正在处理你自己的交易.您是否考虑将JAX-RS服务实现为会话bean,并利用JTA进行事务处理?例如:

> http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-45.html

原文地址:https://www.jb51.cc/java/123650.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐