- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个简单的 Java Web 应用程序,它从数据库接收一些信息并在 Web 浏览器中显示该信息。 Hibernate 用于与 servlet 和 jsp 文件中的数据库进行交互。一切都如我所愿,但我不明白一些事情。
数据库很简单 - 2 个表:问题和答案。表之间的关系是一对多:一个问题可以有多个答案。
这是java类的代码问题和答案:
问题.java
package app;
import java.util.Set;
public class Question {
Long id = null;
String text = "";
Set<Answer> answers = null;
public Question() {
}
public void setId(Long id) {
this.id = id;
}
public void setText(String text) {
this.text = text;
}
public void setAnswers(Set<Answer> answers) {
this.answers = answers;
}
public Long getId() {
return id;
}
public String getText() {
return text;
}
public Set<Answer> getAnswers() {
return answers;
}
}
Answer.java
package app;
public class Answer {
Long id = null;
String text = "";
Question question = null;
public Answer() {
}
public void setId(Long id) {
this.id = id;
}
public void setText(String text) {
this.text = text;
}
public void setQuestion(Question question) {
this.question = question;
}
public Long getId() {
return id;
}
public String getText() {
return text;
}
public Question getQuestion() {
return question;
}
}
这是 Hibernate 的配置:
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver://localhost;databaseName=Test</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping resource="question.hbm.xml"/>
<mapping resource="answer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
question.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="app">
<class name="app.Question" table="Question">
<id column="id" name="id" type="java.lang.Long">
<generator class="native"/>
</id>
<property column="text" name="text" not-null="true" type="java.lang.String"/>
<set name="answers">
<key column="question_id"/>
<one-to-many class="app.Answer"/>
</set>
</class>
</hibernate-mapping>
answer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="app">
<class name="app.Answer" table="Answer">
<id column="id" name="id" type="java.lang.Long">
<generator class="native"/>
</id>
<property column="text" name="text" not-null="true" type="java.lang.String"/>
<many-to-one class="app.Question" column="question_id" name="question" not-null="true"/>
</class>
</hibernate-mapping>
所以在问题中有一个答案的集合。因此,将会有一个懒惰的答案加载。我想在 jsp 文件中使用 Hibernate 对象,因此我使用 this technique :过滤器用于创建一个 session ,该 session 在servlet和相应的jsp文件中都使用。
这是我的过滤器的代码:
HibernateFilter.java
package app;
import java.io.IOException;
import javax.servlet.*;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateFilter implements Filter {
private SessionFactory sessionFactory;
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
try {
sessionFactory.getCurrentSession().beginTransaction();
chain.doFilter(request, response);
sessionFactory.getCurrentSession().getTransaction().commit();
} catch (Exception ex) {
sessionFactory.getCurrentSession().getTransaction().rollback();
ex.printStackTrace();
}
}
public void init(FilterConfig filterConfig) throws ServletException {
sessionFactory = new Configuration().configure().buildSessionFactory();
}
public void destroy() {
}
}
我的应用程序中有两个 servlet 和两个相应的 jsp 文件 - 第一个显示 ID = 1 的问题,第二个显示所有问题。这是这个servlet的代码,相应的jsp文件和tomcat的配置:
GetOneQuestion.java
package app;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class GetOneQuestion extends HttpServlet {
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
try {
Session session = new Configuration().configure()
.buildSessionFactory().getCurrentSession();
session.beginTransaction();
Question question = (Question)session.load(Question.class, 1L);
//session.getTransaction().commit();
request.setAttribute("oneQuestion", question);
} catch (Exception ex) {
ex.printStackTrace();
request.setAttribute("oneQuestion", null);
}
RequestDispatcher view = request.getRequestDispatcher("/oneQuestion.jsp");
view.forward(request, response);
}
}
oneQuestion.jsp
<%@page import="app.Answer"%>
<%@page import="app.Question"%>
<html>
<body>
<%
Question question = (Question)request.getAttribute("oneQuestion");
out.print("<br>" + question.getText() + "<br><br>");
%>
</body>
</html>
GetAllQuestion.java
package app;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.List;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
public class GetAllQuestion extends HttpServlet {
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
try {
Session session = new Configuration().configure()
.buildSessionFactory().getCurrentSession();
session.beginTransaction();
Query query = session.createQuery("from Question");
List all = query.list();
request.setAttribute("allQuestion", all);
} catch (Exception ex) {
ex.printStackTrace();
request.setAttribute("allQuestion", null);
}
RequestDispatcher view = request.getRequestDispatcher("/allQuestion.jsp");
view.forward(request, response);
}
}
allQuestion.jsp
<%@page import="app.Answer"%>
<%@page import="app.Question"%>
<%@page import="java.util.List"%>
<html>
<body>
<%
List all = (List)request.getAttribute("allQuestion");
for (Object object : all) {
Question question = (Question)object;
out.print("<br>Question " + question.getId());
for (Answer answer : question.getAnswers()) {
out.print("<br>" + answer.getText() + "<br>");
}
}
%>
</body>
</html>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>app.HibernateFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>getAllQuestion</servlet-name>
<servlet-class>app.GetAllQuestion</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getAllQuestion</servlet-name>
<url-pattern>/getAllQuestion</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getOneQuestion</servlet-name>
<servlet-class>app.GetOneQuestion</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getOneQuestion</servlet-name>
<url-pattern>/getOneQuestion</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
问题
1) 为什么我需要在 servlet 中调用“session.beginTransaction()”方法,即使我已经在过滤器中调用了“session.beginTransaction()”方法?如果我从另一个 servler 调用一个 servler,我还必须在第二个 servlet 中调用此方法吗?或者我必须在每次与数据库交互之前调用此方法?
2)我不在过滤器中调用“sessionFactory.getCurrentSession().openSession()”或“sessionFactory.getCurrentSession().getCurrentSession()”,但我在中调用“sessionFactory.getCurrentSession().getCurrentSession()” servlet 并仍然获取似乎在过滤器中创建的 session 。怎么会这样?
3) 如果我取消注释行“session.getTransaction().commit();”在 jsp 文件中的 GetOneQuestion 类中,即使此 jsp 文件中没有延迟加载,我也会收到 LazyInitializationException:“无法初始化代理 - 无 session ”,因为我在那里不使用任何 Answer 对象。是什么原因导致这个异常呢?即使没有延迟加载, session 也必须打开才能与 Hibernate 对象进行任何交互?
最佳答案
您可以将 session 工厂存储在应用程序初始值设定项类的静态字段中,并在 servlet 中从中获取当前 session 。
关于您的问题
getCurrentSession()
返回一个通过ThreadLocal
绑定(bind)到当前线程的 session (并非总是如此,这取决于配置)。question.getAnswers()
中遇到 LazyInitializationException
。 关于java - openSession()、getCurrentSession()、beginTransaction()、延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34809297/
当您只打算执行一个查询而不删除或更新数据时,是否真的有必要启动事务? 我目前正在使用带有 C3p0 的 Hibernate 4.1.9 示例, session session = hibernateu
以下 BeginTransaction 方法有什么区别: SqlConnection.BeginTransaction 方法 DbConnection.BeginTransaction 方法 DbCo
考虑以下: /** (Cas_Template_Tree::DeleteNode) * Deletes the given node from the tree, and all of it's c
我将使用SQLite help page中有关外键约束的示例: 让我们在SQLite中构建2个表: CREATE TABLE artist( artistid INTEGER PRIMARY
当使用最新版本的 System.Data.SQLite nuget 包创建一个简单的 SQLite 事务时,我注意到 SQLiteConnection.BeginTransaction() 方法的智能
我在多线程 Windows 桌面程序中使用 SQLite (System.Data.SQLite.dll)。我使用这段代码: using (var cn = new SQLiteConnection(
我有以下代码: $db->beginTransaction(); $achievement_name = $db->prepare("SELECT `achievement_name` FROM `a
在EF6、MVC、MySQL场景下,使用EF TransactionScope和DBContext.BeginTransaction有什么区别? TransactionScope 中没有显式回滚。 应
我目前正在重构我的代码并收到以下错误: Uncaught PDOException: There is no active transaction in... class Dbh { pri
我正在尝试提交到我的数据库,但在我尝试执行查询时收到一个异常,指出该数据库未打开。谁能解释我在这里做错了什么? GetConnectionString(DbMap) 肯定会返回正确的字符串,因为我在执
当两个不同的客户端调用具有 pdo::beginTransaction 的同一个 php 函数时会发生什么? 其中一个是否失败,或者两个 php 实例是否可以执行 beginTranscation 提
done = $connection; } public function createAction() { //create a new item
我有两个 fragment 并将它们设置如下 fram1 = new FragMent1(); fragMentTra.addToBackStack(null); fragMentTra = getF
我想把json解析出来的数据批量插入到db中。我使用下面的方法插入批处理。问题是 mDbWritable.beginTransaction();执行时间太长。通常像6秒!我不知道问题在哪里。一些想法是
我在尝试从第一个 fragment 启动 fragment 时遇到此错误: java.lang.NullPointerException: Attempt to invoke virtual meth
我的 php error_log 中出现以下错误 PHP Warning: Error while sending QUERY packet. PID=29770 in /home/test/test
我有一个原子事务的实现,其中在异步 HTTP POST 方法中更新了许多上下文。 在事务实现之前,我正在异步操作我的上下文 例如( await _context.Foo.AddAsync(trade)
好的,抱歉,主题名称太长了... 如果我执行以下操作: using (var transaction = session.BeginTransaction()) { // do somethi
我有一个简单的 Java Web 应用程序,它从数据库接收一些信息并在 Web 浏览器中显示该信息。 Hibernate 用于与 servlet 和 jsp 文件中的数据库进行交互。一切都如我所愿,但
我使用 FragmentPagerAdapter 在我的 ViewPgaer 中有 4 个 fragment 。我尝试在持续延迟后添加每个 fragment ,以便在切换底部栏选项卡时获得无抖动的动画
我是一名优秀的程序员,十分优秀!