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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |