Hibernate对Web应用程序更安全吗?

我怀疑Hibernate对于Web应用程序(JSP,Servlet,Hibernate,MySQL)是否安全,它将“不同用户”“一次”获得数千个访问权限。

我担心的原因如下。

想象一下,我有一个学生的网络应用程序。 他们有自己的个人资料,并将维持自己的学生课程,标记等。 现在,肯定有超过1个用户将一直在线,拥有自己的个人资料。 这意味着如果用户A对其数学标记进行了编辑,则将在用户A的配置文件中完成。 在所有同时在线的用户AB和’C`s配置文件中永远不会被替换。

Servlets是multithreading的,以提供上述支持。 它与纯JDBC一样可以正常工作。 Hibernate怎么样?

我还上传了我的HibernateUtil供您参考。 在我的情况下,我将其称为SessionFactoryBuilder

 public class SessionFactoryBuilder { private static SessionFactoryBuilder instance; private static SessionFactory sessionFactory; private SessionFactoryBuilder() { buildConfig(); System.out.println("hehehehe"); } private static void buildConfig() { Configuration configuration = new Configuration().configure(); StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()); sessionFactory = configuration.buildSessionFactory(builder.build()); } public static SessionFactoryBuilder getInstance() { if(instance == null) { instance = new SessionFactoryBuilder(); } return instance; } public SessionFactory getSessionFactory() { return sessionFactory; } } 

1)在Hibernate中,每个应用程序都存在一个Single SessionFactory对象
SessionFactory的内部状态是不可变的因此它是线程安全的 。 多个线程可以同时访问它以获取Session实例。

下面的代码描述了通过Utility类获取SessionFactory实例的标准方法。

 import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; /** * Hibernate Utility class with a method to get Session Factory object. */ public class HibernateUtil { private static final SessionFactory sessionFactory;//Once created, its properties cannot be changed static { try { // Create the SessionFactory from standard (hibernate.cfg.xml) config file. sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); } catch (Throwable ex) { // Log the exception. System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } } 

2) Hibernate Session是java应用层和hibernate之间的接口。 这是用于执行数据库操作的核心接口。 会话的生命周期受逻辑事务的开始和结束的限制。

Hibernate Session对象不是线程安全的 ,每个线程都应该获得它自己的会话实例,并在它完成工作后关闭它。

它并不意味着/意味着实现者是线程安全的。 相反,每个线程/事务应从SessionFactory获取自己的实例。

 A typical transaction should use the following idiom: Session sess = factory.openSession(); Transaction tx; try { tx = sess.beginTransaction(); //do some work ... tx.commit(); } catch (Exception e) { if (tx!=null) tx.rollback(); throw e; } finally { sess.close(); } 

如果会话抛出exception,则必须回滚事务并丢弃会话。 发生exception后,Session的内部状态可能与数据库不一致。

2.1)下面列出了两种广泛用于获取Hibernate会话对象的方法。

  1. openSession //用于multithreading环境
  2. getCurrentSession //用于单线程环境

Hibernate SessionFactory getCurrentSession()方法返回绑定到上下文的会话。 但为了实现这一点,我们需要在hibernate配置文件中配置它。 由于此会话对象属于hibernate上下文,因此我们不需要关闭它。 关闭SessionFactory后,此会话对象将关闭。

 thread 

Hibernate SessionFactory openSession()方法总是打开一个新会话。 完成所有数据库操作后,我们应该关闭此会话对象。
我们应该在multithreading环境中为每个请求打开一个新会话。


2.2)还有一种方法是使用openStatelessSession()创建Hibernate Session对象,它为您提供一个hibernate无状态会话。

它是一个面向命令的API,用于对数据库执行批量操作。
无状态会话不实现第一级高速缓存,也不与任何二级高速缓存交互,也不实现事务性后写或自动脏检查,也不操作级联到关联实例。 无状态会话将忽略集合。 通过无状态会话执行的操作绕过Hibernate的事件模型和拦截器。 由于缺少第一级缓存,无状态会话容易受到数据别名影响。

对于某些类型的事务,无状态会话的执行速度可能比有状态会话略快(例如:批处理/批量更新)

 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(); 

在此代码示例中,查询返回的Customer实例将立即分离。 它们永远不会与任何持久化上下文相关联。

由StatelessSession接口定义的insert(),update()和delete()操作被视为直接数据库行级操作。 它们分别导致立即执行SQL INSERT,UPDATE或DELETE。

无状态会话不是线程安全的 ,使用无状态会话时可能发生exception是“org.hibernate.AssertionFailure:可能的非线程安全访问会话”


3)您的学生记录项目是一个multithreading应用程序,因此在使用hibernate时需要小心。 尝试通过打开新会话,使用事务,提交和回滚以及在需要时关闭会话来使用最佳编程实践。

我个人在我们的项目中使用了hibernate,我们有数百万用户通过hibernate作为后端API访问数据库。 我们在multithreading环境中从未遇到过这样的问题,因为我们使用了hibernate的最佳编程实践。 即使DB发生任何exception,也会回滚整个事务。

因此,与JDBC相比,数据库事务的ACID属性(primefaces性,一致性,隔离性,持久性)可以以更高的成功率实现。