- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在阅读 Java Persistence with Hibernate 第二版。我在书中找到了以下引文,但我不太清楚。
Another issue to consider is dirty checking. Hibernate automatically detects state changes in order to synchronize the updated state with the database. It’s usually safe to return a different instance from the getter method than the instance passed by Hibernate to the setter. Hibernate compares them by value—not by object identity—to determine whether the attribute’s persistent state needs to be updated. For example, the following getter method doesn’t result in unnecessary SQL UPDATEs:
public String getFirstName(){
return new String(firstName);
}
我的问题是为什么返回一个新的 String 对象不会进行不必要的 SQL 更新,它与仅返回 firstName 有什么不同?
当我尝试运行 getFirstName 时,我没有看到任何更新查询被触发。
请告诉我,因为我不清楚。
下面是代码:
package org.prashdeep.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class User {
protected Long id;
@Id
@GeneratedValue()
public Long getId() { // Optional but useful
return id;
}
protected String firstName;
protected String lastName;
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
System.out.println("Called from the setter of lastname");
this.lastName = lastName;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
SaveUserEntity.java
package org.prashdeep.executor;
import bitronix.tm.resource.jdbc.PoolingDataSource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment;
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl;
import org.hibernate.service.ServiceRegistry;
import org.prashdeep.common.DatabaseProduct;
import org.prashdeep.model.User;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import java.util.List;
public class SaveUserEntity {
protected Context context;
protected PoolingDataSource dataSource;
public static String DATASOURCE_NAME = "myDS";
public DatabaseProduct databaseProduct;
public UserTransaction getUserTransaction() {
try {
return (UserTransaction) context.lookup("java:comp/UserTransaction");
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public void rollback() {
UserTransaction tx = getUserTransaction();
try {
if (tx.getStatus() == Status.STATUS_ACTIVE ||
tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
tx.rollback();
} catch (Exception ex) {
System.err.println("Rollback of transaction failed, trace follows!");
ex.printStackTrace(System.err);
}
}
protected SessionFactory createSessionFactory() throws Exception{
this.dataSource = new PoolingDataSource();
dataSource.setUniqueName(DATASOURCE_NAME);
dataSource.setMinPoolSize(1);
dataSource.setMaxPoolSize(5);
dataSource.setPreparedStatementCacheSize(10);
dataSource.setIsolationLevel("READ_COMMITTED");
dataSource.setClassName("org.h2.jdbcx.JdbcDataSource");
dataSource.setAllowLocalTransactions(true);
dataSource.getDriverProperties().put(
"URL",
"jdbc:h2:mem:test"
);
dataSource.getDriverProperties().put("user", "sa");
context = new InitialContext();
dataSource.init();
/*
This builder helps you create the immutable service registry with
chained method calls.
*/
StandardServiceRegistryBuilder serviceRegistryBuilder =
new StandardServiceRegistryBuilder();
/*
Configure the services registry by applying settings.
*/
serviceRegistryBuilder
.applySetting("hibernate.connection.datasource", "myDS")
.applySetting("hibernate.format_sql", "true")
.applySetting("hibernate.show_sql", "true")
.applySetting("hibernate.hbm2ddl.auto", "create-drop");
// Enable JTA (this is a bit crude because Hibernate devs still believe that JTA is
// used only in monstrous application servers and you'll never see this code).
serviceRegistryBuilder.applySetting(
Environment.TRANSACTION_COORDINATOR_STRATEGY,
JtaTransactionCoordinatorBuilderImpl.class
);
ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
/*
You can only enter this configuration stage with an existing service registry.
*/
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
/*
Add your persistent classes to the (mapping) metadata sources.
*/
metadataSources.addAnnotatedClass(
org.prashdeep.model.User.class
);
// Add hbm.xml mapping files
// metadataSources.addFile(...);
// Read all hbm.xml mapping files from a JAR
// metadataSources.addJar(...)
MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder();
Metadata metadata = metadataBuilder.build();
SessionFactory sessionFactory = metadata.buildSessionFactory();
return sessionFactory;
}
public static void main(String args[]) throws Exception {
SaveUserEntity obj = new SaveUserEntity();
SessionFactory sessionFactory = obj.createSessionFactory();
try {
{
/*
Get access to the standard transaction API <code>UserTransaction</code> and
begin a transaction on this thread of execution.
*/
UserTransaction tx = obj.getUserTransaction();
tx.begin();
/*
Whenever you call <code>getCurrentSession()</code> in the same thread you get
the same <code>org.hibernate.Session</code>. It's bound automatically to the
ongoing transaction and is closed for you automatically when that transaction
commits or rolls back.
*/
Session session = sessionFactory.getCurrentSession();
User user = new User();
user.setFirstName("Pradeep");
user.setLastName("Kumar");
/*
The native Hibernate API is very similar to the standard Java Persistence API and most methods
have the same name.
*/
session.persist(user);
/*
Hibernate synchronizes the session with the database and closes the "current"
session on commit of the bound transaction automatically.
*/
tx.commit();
}
{
UserTransaction tx = obj.getUserTransaction();
tx.begin();
/*
A Hibernate criteria query is a type-safe programmatic way to express queries,
automatically translated into SQL.
*/
List<User> users =
sessionFactory.getCurrentSession().createCriteria(
User.class
).list();
// SELECT * from MESSAGE
users.get(0).setFirstName("Praveen");
System.out.println(users.get(0).getFirstName());
tx.commit();
}
} finally {
obj.rollback();
}
}
}
最佳答案
假设在数据库中,您有一条 firstName
为 FOO
的记录。在某些时候,该记录会作为持久实体加载,因此您现在拥有一个 User
类型的 Java 对象,其中 getFirstName()
返回一个字符串 "FOO"
.
当您使用 setFirstName("BAR");
修改持久对象时,下次提交时,将导致 SQL UPDATE。这是因为Hibernate会比较“数据库状态”和“内存状态”,它会发现有区别(FOO
变成了BAR
),然后他就会启动SQL 更新。到目前为止都是标准的。
现在 Hibernate 手册试图指出的一点是,这种比较是基于 equals
而不是 ==
。在我们的示例中,它将检查字符串值 FOO
和 BAR
是否相等(概念上是 oldValue.equals(newValue)
),而不是返回相同的 String 对象 (oldValue == newValue
)。
因此,他们的示例是:您可以返回 new String(firstName)
,它是一个不同的 String 对象,但 equals
是相同的。
希望这对您有帮助。
关于java - Hibernate脏检查查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42248327/
Android 似乎真的不喜欢invalidate (Rect dirty),它用于仅使 Canvas 的一部分无效。当我使 Canvas 的一部分(下面以绿色显示)无效并且需要同时重绘 Canvas
来自 Leoliger 2ed 的 Git 版本控制, After you commit the addition of the new file into the repository, git s
我使用基本的 Valgrind 工具时出现了意外行为。对于基本 block 的每个 Put 语句,我使用以下方法注册一个脏助手unsafeIRDirty_0_N。问题是脏助手被调用的次数比预期的多,例
我想知道是否有人可以告诉我 hibernate 脏 session 是什么?我似乎遇到了一个问题,条件查询在不应该执行插入时执行了插入。我相信这与脏 session 有关,但在不真正了解脏 sessi
我正在尝试构建一个用于通用添加标签的 ADF 映射数据流 - 其目的是查看特定列中的值并将其替换为标签。我已经有了如下所示的数据集(表 B): enter image description here
我需要在刷新所有更改的实体之前编写一些业务逻辑。我尝试过的解决方案之一是 IPreUpdateEventListener。但是这个事件监听器已经将对象非规范化为键值。我需要在非规范化甚至刷新之前的一些
基于此help link我能够实现颜色更改,但在此解决方案中,它将颜色应用于整行,这不是我想要的。 我想更改唯一编辑过的单元格的颜色。如果有人有任何想法,请分享。谢谢。 最佳答案 这是一个带有您想要的
我想做什么? 我正在尝试反编译一个 apk 文件,修改它并重新编译它。 我的工作环境是什么? root@l0calh0st:~/Desktop/APKS/Projects# uname -a Linu
“ps”和“top”等工具报告各种内存使用情况,例如 VM 大小和驻留集大小。但是,这些都不是“真正的”内存使用情况: 程序代码在同一程序的多个实例之间共享。 共享库程序代码在使用该库的所有进程之间共
Martin Fowler说我们应该在添加新功能之前进行重构(假设原始程序结构不佳)。 所以我们都想重构这个脏代码库,这是肯定的。我们还知道,如果没有单元测试代码,就很容易引入细微的错误。 但这是一个
在开始开发一些实验性的东西之前,我创建了一个新分支。我通常会忘记这一点(这不是问题),但现在我事先做了。 从那以后,我更新了 3 个文件。 在 2 中只是我不想提交到安全分支的实验性更改。 在 1 中
这是代码的精简版本: gridDataSource = new kendo.data.DataSource({ batch: true, transport: {
内容: 我正在使用azure广告构建一个简单的登录应用程序,该应用程序可以正常登录并获取 token ,然后可以重定向到下一页,但是在重定向之前会引发错误 错误: The following _Typ
我想将我的摘要字段设置为 body 字段的清理版本,但前提是用户不提供他们自己的摘要,即。 params[:document][:summary] 为空。 如果我创建一个新记录,这似乎工作正常,如果我
我正在使用乐观锁定来防止人们在竞争条件下覆盖彼此的变化。 因为我从 5.1 升级了 Rails至 5.2 ,我的规范坏了,我将其追溯到 changes 中的事实。数组,与文件上传相关的更改不再Uplo
我似乎无法解决这个问题,所以如果有人可以帮助我,请您坚持一下! import 'dart:async'; import 'dart:convert'; import 'package:http/htt
我是一名优秀的程序员,十分优秀!