2011-06-13 62 views
2

我在使用@Produces时遇到JAXRS/JAXB问题,包括JSON结果中的子标识。以下是我的代码的一部分。因为我们使用Hibernate,所以我将这个id抽象成一个AbstractEntity类。使用JAXRS返回子标识

的POJO:

@XmlRootElement 
public abstract class AbstractEntity implements Serializable { 
    private Serializable id; 

    @XmlElement(type-Object.class) 
    @XmlSchemaType(name="anySimpleType") 
    public final Serializable getId() { 
     return this.id 
    } 

    public final Serializable setId(Serializable id) { 
     this.id = id; 
    } 
} 

@XmlRootElement 
public class Parent extends AbstractEntity { 
    private String parentName; 
    private Child child; 

    @XmlElement 
    public String getParentName() { 
     return parentName; 
    } 

    @XmlElement 
    public Child getChild() { 
     return child; 
    } 

} 

@XmlRootElement 
public class Child extends AbstractEntity { 

    private String childName; 

    @XmlElement 
    public String getChildName() { 
     return childName; 
    } 

} 

JAXRS服务:

@Path("/parent") 
public class ParentService { 

    @GET 
    @Path("/get/{id}") 
    @Produces(MediaType.APPLICATION.JSON) 
    public Parent getById(@PathParam("id") Long id) { 

     Parent parent = hibernateDataController.getParentById(id); 

     if (parent== null) 
      throw new NotFoundException("GET: Parent" + id + " not found."); 

     return parent; 

    } 
} 

@Path("/child") 
public class ChildService { 

    @GET 
    @Path("/get/{id}") 
    @Produces(MediaType.APPLICATION.JSON) 
    public Child getById(@PathParam("id") Long id) { 

     Child child = hibernateDataController.getChildById(id); 

     if (child == null) 
      throw new NotFoundException("GET: Child " + id + " not found."); 

     return child; 

    } 
} 

(注:没有显示更多的代码,但主要部分是以上)

我的项目是在Eclipse中,使用Maven,所以我开启了码头:mvn码头:运行

这是问题出现的地方。我可以通过访问子POJO:

http://myserver:8080/example/child/get/1 returns->

{ 
    "id":{"@type":"xs:long","$":"1"}, 
    "childName":"Bart Simpson" 
} 

但是,当我访问父POJO,孩子的id没有返回POJO:

http://myserver:8080/example/parent/get/1回报 - >

{ 
    "id":{"@type":"xs:long","$":"1"}, 
    "parentName":"Homer Simpson", 
    "child": { 
     "childName":"BartSimpson" 
    } 
} 

请注意,没有返回孩子的ID,只是childName。我正在使用的GUI团队正在使用GWT,他们要求我在JSON结果中包含任何孩子的ID。

任何帮助获取JAXRS/JAXB返回子JSON内的ID将不胜感激。谢谢你的时间。

马特

+0

如果可能的话,你可以让'id'属性比'long''Serializable'更具体,这将消除'type'(真正的xsi:type)属性被写出来。 – 2011-06-13 18:17:35

+0

不幸的是,我们的数据模型有点“搞砸了”。我们的一些表格使用Long作为ID,其他使用UUID。我选择了Serializable,因为它涵盖了Long和UUID。我仍然想要一个DAO控制器来处理所有的表格。 – 2011-06-13 20:22:26

+0

你的'ParentService'正在返回一个'Person'。在转换为SO问题时,您的层次结构中是否存在另一个级别,或者只有一个错字? – bamana 2011-06-13 21:13:22

回答

0

今天早上我找到了我对失踪孩子ID的解决方案。它实际上不是JAXRS/JAXB问题,而是由Hibernate映射文件引起的(是的,我仍然喜欢使用映射文件来覆盖Hibernate的注释)。

用于例如文件Hibernate映射文件以上将是:

<hibernate-mapping> 
    <class name="com.mycompany.Parent" table="PARENT"> 
    <id name="id" type="java.lang.Long"> 
     <column name="PARENT_ID" scale="0" /> 
     <generator class="native" /> 
    </id> 
    <property name="parentName" type="java.lang.String"> 
     <column name="PARENT_NAME" /> 
    </property> 
    <set name="children" inverse="true" lazy="true" table="CHILD" fetch="select"> 
     <key> 
     <column name="CHILD_ID" /> 
     </key> 
     <one-to-many class="com.mycompany.Child" /> 
    </set> 
    </class> 
</hibernate-mapping> 

<hibernate-mapping> 
    <class name="com.mycompany.Child" table="CHILD"> 
    <id name="id" type="java.lang.Long"> 
     <column name="CHILD_ID" scale="0" /> 
     <generator class="native" /> 
    </id> 
    <property name="childName" type="java.lang.String"> 
     <column name="CHILD_NAME" /> 
    </property> 
    <many-to-one name="parent" type="com.mycompany.Child" fetch="select"> 
     <column name="PARENT_ID" /> 
    </many-to-one> 
    </class> 
</hibernate-mapping> 

此修复程序是强制Hibernate不是“懒惰负载”的孩子。我改变:

<set name="children" inverse="true" **lazy="true"** table="CHILD" **fetch="select"**> 

到:

<set name="children" inverse="true" lazy="false" table="CHILD" **fetch="join"**> 

与修改后的Hibernate映射文件的ID来通过JAXRS结果:

{ 
    "id":{"@type":"xs:long","$":"1"}, 
    "parentName":"Homer Simpson", 
    "child": { 
     "id":{"@type":"xs:long","$":"1"}, 
     "childName":"BartSimpson" 
    } 
} 

希望这会帮助,如果别人跑进这个问题。