OpenSessionInViewFilter级联合并问题

时间:2014-03-12 11:28:27

标签: java spring hibernate spring-mvc

我正在使用OpenSessionInViewFilter,Spring和Hibernate进行数据访问。 OpenSessionInViewFilter配置如下

<filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>sessionFactoryBeanName</param-name>
            <param-value>sessionFactory</param-value>
        </init-param>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>false</param-value>
        </init-param>
    </filter>

现在我已经用注释映射了实体,就像那样

@Entity
@Table(name = "SERVICE_USER")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ServiceUser implements Serializable {

@Id
@GeneratedValue(generator = "service_user_id_generator", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(name = "service_user_id_generator", sequenceName = "service_user_id_gen", allocationSize = 1)
    private Long id;

@ManyToOne
    @JoinColumn(name = "contract_type_id")
    @ForeignKey(name = "service_user_ct_fk")
    private ServiceUserContractType contractType;

}

现在我正在尝试构建并保存新的ServiceUser实体。为此,我有从数据库中检索ServiceUserContractType的服务,并在新创建的服务用户中设置相应的字段。从标记为事务的数据库获取contarct类型的方法。

要保存服务用户,请使用

sessionFactory.getCurrentSession().merge(serviceUser)

如果我尝试使用此方法来审核合同类型

public ServiceUserContractType getContractType(Long id){
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ServiceUserContractType.class);

        criteria.add(Restrictions.eq("id", id));

        return (ServiceUserContractType) criteria.uniqueResult();
    }

然后,合并的那一刻叫我收到

object references an unsaved transient instance - save the transient instance before flushing

异常。我明白了,我在服务用户映射中将cascade = CascadeType.MERGE添加到@ManyToOne注释,它可以正常工作。但... 如果我使用

public ServiceUserContractType getContractType(Long id){
        return (ServiceUserContractType) sessionFactory.getCurrentSession().load(ServiceUserContractType.class, id);
    }

没有级联合并选项,它可以正常工作。 我在调试时看到的唯一区别是第一个方法(带条件)返回完全加载的合同类型实体,load变量返回未初始化的代理。

有人可以解释这种情况下的工作原理吗?为什么代理可以在没有级联的情况下合并?为什么标准不是代理而是完全初始化的实体?

0 个答案:

没有答案