【问题标题】:could not initialize proxy - no Session in jax-ws + hibernate无法初始化代理 - jax-ws + hibernate 中没有会话
【发布时间】:2013-05-28 12:10:39
【问题描述】:

我坚持使用 JAX-WS 公开 Web 服务。由于 JAXB 在休眠关闭会话后尝试序列化对象而出现问题。我在过去两天谷歌但无法找到正确的答案。以下是其他人给出的一些解决方案。

  • 急切加载对象
  • 使用@XmlTransient
  • SOAPHandler 但未完成回答

这里是详细的场景。我写了一个模型类,它有多个@OneTOMany 关系、@ManyToOne 关系和@OneToOne 关系。结果,Web 服务返回该类的对象。当我通过 SOAP UI 调用服务时,它会给我以下错误消息。

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>could not initialize proxy - no Session</faultstring>
      </S:Fault>
   </S:Body>
</S:Envelope> 

模型类(没有 getter 和 setter)

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
@Entity
@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "mas_form_id")),
        @AttributeOverride(name = "tenantId", column = @Column(name = "mas_form_tenant_id")) })
@FilterDef(name = "tenantFilter", parameters = @ParamDef(name = "tenantIdParam", type = "string"))
@Filters(@Filter(name = "tenantFilter", condition = "mas_form_tenant_id = :tenantIdParam"))
@Table(name = "mas_form")
public class Form extends BaseRevolution {

    @Column(name = "mas_form_action")
    private String formAction;
    @Column(name = "mas_form_is_active")
    private boolean isActive;
    @Column(name = "mas_form_is_lock")
    private boolean isLock;
    @ManyToOne
    @JoinColumn(name = "mas_ft_id")
    private FormType formType;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = FORM)
    private List<FormQuestion> formQuestions = new ArrayList<FormQuestion>(0);
    @OneToMany(fetch = FetchType.LAZY, mappedBy = FORM)
    @LazyCollection(LazyCollectionOption.FALSE)
    private Set<DocumentRequired> documentRequiredSet = new HashSet<DocumentRequired>(0);
    @OneToMany(fetch = FetchType.LAZY, mappedBy = FORM)
    private List<Application> applications = new ArrayList<Application>(0);
    @OneToMany(fetch = FetchType.LAZY, mappedBy = FORM)
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<FormField> formFields = new ArrayList<FormField>(0);
    @OneToMany(fetch = FetchType.LAZY, mappedBy = FORM)
    private List<FormCharge> formCharges = new ArrayList<FormCharge>(0);
    @Column(name = "mas_form_method")
    private String formMethod;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = FORM)
    private List<FormFieldGroup> formFieldGroup;
    @Column(name = "mas_form_name_en")
    private String formNameEn;
    @Column(name = "mas_form_name_si")
    private String formNameSi;
    @Column(name = "mas_form_name_ta")
    private String formNameTa;
    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "activity")
    private ElgActivity elgActivity;
    @Column(name = "description", nullable = true, length = 1000)
    private String description;

    //getters and setters

}

网络服务接口

@WebService(name = "formWebServicePort", targetNamespace = "http://lk.gov.elg/core/ws/form/")
public interface FormWebService {

    @WebMethod(operationName = "getAllFormsWithDocumentReferences", action = "urn:GetAllFormsWithDocumentReferences")
    @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
    @WebResult(name = "formsWithDocumentReferences")
    List<Form> getAllFormsWithDocumentReferences(
            @WebParam(name = "tenantId", targetNamespace = "http://lk.gov.elg/core/ws/form/") String tenantId,
            @WebParam(name = "categoryName", targetNamespace = "http://lk.gov.elg/core/ws/form/") String categoryName);
}

网络服务实现

@SchemaValidation
@WebService(targetNamespace = "http://lk.gov.elg/core/ws/form/", endpointInterface = "lk.gov.elg.core.ws.citizen.FormWebService")
public class FormWebServiceImpl extends SpringBeanAutowiringSupport implements FormWebService {

    private static final Logger logger = LoggerFactory.getLogger(FormWebServiceImpl.class);
    @Autowired
    private FormService formService;

    @Override
    public List<Form> getAllFormsWithDocumentReferences(
            @WebParam(name = "tenantId", targetNamespace = "http://lk.gov.elg/core/ws/form/") String tenantId,
            @WebParam(name = "categoryName", targetNamespace = "http://lk.gov.elg/core/ws/form/") String categoryName) {

        List<Form> formList = formService.getAllFormsWithDocRefs(tenantId, categoryName);
        return formList;
    }
}

帮助我克服这个问题。提前致谢。

【问题讨论】:

    标签: hibernate jaxb jax-ws


    【解决方案1】:

    您是否尝试在退出会话之前初始化表单实体的集合。这会导致加载集合。所以基本上它会做同样的急切加载,但不知何故急切加载并不总是有帮助。如果需要,我可以稍后或明天挖掘更多细节。

    【讨论】:

    • 嗨,Carsten,我需要更多详细信息。请帮忙。我从您的回复中得到的是,我们需要在 Collection 的 getter 方法返回 Form 实体之前调用它。是这样吗 ???谢谢。
    • 是的,这是正确的。您可以在离开会话/事务之前通过调用 Hibernate.initialize(Form.getAnyCollection()); 来初始化集合。至少这对我有用。
    【解决方案2】:

    只是一个想法:我们最近通过向 sessionbean 添加一个 (EJB3) 拦截器方法来克服这个问题(我们使用的是 JBoss7):

    @javax.interceptor.AroundInvoke
    public Object intercept(InvocationContext ctx) throws Exception {
            Object result = ctx.proceed();
    
            // Add code here to inspect the result and initialize all collections.
    
            return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-11-09
      • 2010-11-15
      • 1970-01-01
      • 1970-01-01
      • 2016-12-27
      • 2014-01-14
      • 2020-06-07
      • 1970-01-01
      • 2013-03-03
      相关资源
      最近更新 更多