我正在使用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;
我的子类看起来像这样:
这将创建一个看起来像应该工作的模式,但是在持久化操作期间在服务器端看到的所有模式都是一个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类完全退出.
解决方法
- 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