Hibernate_StatelessSession

Hibernate_StatelessSession


Alternatively, Hibernate provides a command-oriented API that can be used for streaming data to and from the database in the form of detached objects. A StatelessSession has no persistence context associated with it and does not provide many of the higher-level life cycle semantics. In particular, a stateless session does not implement a first-level cache nor interact with any second-level or query cache. It does not implement transactional write-behind or automatic dirty checking. Operations performed using a stateless session never cascade to associated instances. Collections are ignored by a stateless session. Operations performed via a stateless session bypass Hibernate's event model and interceptors. Due to the lack of a first-level cache, Stateless sessions are vulnerable(易受伤的) to data aliasing effects. A stateless session is a lower-level abstraction that is much closer to the underlying JDBC.

StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
   
ScrollableResults customers = session.getNamedQuery("GetCustomers")
    .scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {
    Customer customer = (Customer) customers.get(0);
    customer.updateStuff(...);
    session.update(customer);
}
   
tx.commit();
session.close();


In this code example, the Customer instances returned by the query are immediately detached. They are never associated with any persistence context.


The insert(), update() and delete() operations defined by the StatelessSession interface are considered to be direct database row-level operations. They result in the immediate execution of a SQL INSERT, UPDATE or DELETE respectively. They have different semantics(语义) to the save(), saveOrUpdate() and delete() operations defined by the Session interface.

下面就来验证,


Collections are ignored by a stateless session

如下对比测试,

@Test
public void test8656() {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    Transaction tx = session.getTransaction();
    tx.begin();
    Role role = (Role) session.get(Role.class, 3);
    if (role.getUsers() != null) {
        System.out.println("users size=" + role.getUsers().size());
    } else {
        System.out.println("users is null");
    }
    tx.commit();
    System.out.println("commit end");
}

下面这个使用openStatelessSession,如下

@Test
public void test766() {
    StatelessSession statelessSession = HibernateUtil.getSessionFactory().
            openStatelessSession();
    Transaction tx = statelessSession.getTransaction();
    tx.begin();
    Role role = (Role) statelessSession.get(Role.class, 3);
    if (role.getUsers() != null) {
        System.out.println("users size=" + role.getUsers().size());
    } else {
        System.out.println("users is null");
    }
    tx.commit();
    System.out.println("commit end");
}

测试结果分别是,

Hibernate: select role0_.id as id1_0_0_, role0_.description as descript2_0_0_, role0_.roleName as roleName3_0_0_ from tb_role role0_ where role0_.id=?
Hibernate: select users0_.role_id as role_id4_0_0_, users0_.id as id1_1_0_, users0_.id as id1_1_1_, users0_.age as age2_1_1_, users0_.name as name3_1_1_, users0_.role_id as role_id4_1_1_ from tb_user users0_ where users0_.role_id=?
users size=100
commit end

Process finished with exit code 0

这个是使用session的,可以看到发出了两条sql,后一条是查询User集合的。

Hibernate: select role0_.id as id1_0_0_, role0_.description as descript2_0_0_, role0_.roleName as roleName3_0_0_ from tb_role role0_ where role0_.id=?

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.lyx.Role.users, could not initialize proxy - no Session
	at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)

这个是statelessSession 请求的Role对象,当我getUsers的时候报错。。同时可以看到只发出了一条sql,没有去查询Role 的user 集合。


一对多关系中,查询多的一端

如下是分别使用session 和 statelessSession 的情况,

@Test
public void test86856756() {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    Transaction tx = session.getTransaction();
    tx.begin();
    User user = (User) session.get(User.class,1);
    System.out.println(user.getRole().getId());
    System.out.println(user.getRole().getRoleName());
    tx.commit();
    System.out.println("commit end");
}

运行结果:

Hibernate: select user0_.id as id1_1_0_, user0_.age as age2_1_0_, user0_.name as name3_1_0_, user0_.role_id as role_id4_1_0_, role1_.id as id1_0_1_, role1_.description as descript2_0_1_, role1_.roleName as roleName3_0_1_ from tb_user user0_ inner join tb_role role1_ on user0_.role_id=role1_.id where user0_.id=?
1
admin
commit end

Process finished with exit code 0

通过发出的sql,可以知道 只发出了一次查询

statelessSession 情况下,如下,

@Test
public void test723266() {
    StatelessSession statelessSession = HibernateUtil.getSessionFactory().
            openStatelessSession();
    Transaction tx = statelessSession.getTransaction();
    tx.begin();
    User user = (User) statelessSession.get(User.class,1);
    System.out.println(user.getRole().getId());
    System.out.println(user.getRole().getRoleName());
    tx.commit();
    System.out.println("commit end");
}

运行情况,如下,

Hibernate: select user0_.id as id1_1_0_, user0_.age as age2_1_0_, user0_.name as name3_1_0_, user0_.role_id as role_id4_1_0_, role1_.id as id1_0_1_, role1_.description as descript2_0_1_, role1_.roleName as roleName3_0_1_ from tb_user user0_ inner join tb_role role1_ on user0_.role_id=role1_.id where user0_.id=?
1
admin
commit end

这两种查询方式发出的sql 一样。。


===========================END===========================


你可能感兴趣的:(Hibernate_StatelessSession)