RESTEasy和Jackson提供程序无法将带有@XmlIDREF和@XmlID的实体序列化为JSON

时间:2015-09-11 17:14:38

标签: json jaxb jackson jax-rs

我有两个实体:

@XmlRootElement(name = "provider")
@XmlAccessorType(XmlAccessType.PROPERTY) 
@Entity    
public class Provider {
  //...
  @XmlElementWrapper(name = "industries")
  @XmlElement(name = "industry")
  @XmlIDREF
  @ManyToMany(mappedBy = "providers", fetch = FetchType.EAGER)
  public Set<Industry> getIndustries() {
    return industries;
  }

}

第二个实体:

@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
@Entity
public class Industry implements Serializable {

     //...
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Basic(optional = false)
     @Column(name = "industry_id", nullable = false /*, columnDefinition = "BIGINT UNSIGNED" */)
     public Long getIndustryId() {
          return industryId;
      }

     public void setIndustryId(Long industryId) {
          this.industryId = industryId;
     }

     //...

     @XmlID
     @Transient
     public String getSelfLink() {
          return getIndustryId().toString();
     }
}

现在使用RESTEasy生成XML和JSON我只能在XML和JSON中获得预期的结果而不是id返回整个Industry实体+异常抛出。

收到正确的XML:

      <provider>
            <userId>8</userId>
            //.... - deleted for simplicity
            <industries>
                <industry>1</industry>
            </industries>
        </provider>

但是JSON中的结果不正确:

{"provider":{ /* deleted for simplicity */ 
"industry":[{"industryId":1,"name":"Bran?a medyczna","description":null,"providers"}]}}

“行业”:1 应该只返回标识符!

抛出异常:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: pl.salonea.entities.Industry.providers, could not initialize proxy - no Session (through reference chain: pl.salonea.jaxrs.utils.ResourceList["resources"]->java.util.ArrayList[0]->pl.salonea.entities.Provider["industry"]->org.hibernate.collection.internal.PersistentSet[0]->pl.salonea.entities.Industry["providers"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:210)

并且:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: pl.salonea.entities.Industry.providers, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
    at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
    at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:160)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:88)

1 个答案:

答案 0 :(得分:2)

我遇到了同样的事情,我通过向@XmlAttribute添加@XmlID注释解决了这个问题。这对我有用。 (注意:我的代码是用Ceylon编写的,而不是Java。)

shared entity class Employee(name, manager) {

    xmlAttribute xmlID
    generatedValue id
    shared late Integer id;

    column { length = 50; }
    shared String name;

    shared variable Integer? year = null;

    xmlIDREF
    manyToOne
    shared Employee? manager;

    xmlTransient
    oneToMany { mappedBy = "manager"; }
    shared Set<Employee> employees = set {};

}

我不知道为什么这是必要的,特别是因为AFAIK @XmlAttribute vs @XmlElement对JSON没有意义。