- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使用 hibernate 持久化克隆对象时遇到了问题。当它的嵌套子项被删除时,记录并没有从数据库中删除(我已经设置了 orphanRemoval = true)。
在下面的代码中,使用 json 创建了一个克隆。在 clone.removeItem() 之后,hibernate 应该在 session.update(clone) 时删除孤立的 Item。但是当我再次查询时它仍然存在。怎么了?
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
public class JacksonTest {
SessionFactory factory;
@BeforeClass
public void setup() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure("hibernate.cfg.xml")
.build();
factory = new MetadataSources(registry)
.addAnnotatedClass(PurchaseOrder.class)
.addAnnotatedClass(Item.class)
.buildMetadata()
.buildSessionFactory();
PurchaseOrder order = new PurchaseOrder(10, LocalDate.now());
order.addItem(new Item(1, "ABC", new BigDecimal("84.50")));
try (Session session = factory.openSession()) {
Transaction tx = session.beginTransaction();
session.save(order);
tx.commit();
}
}
@AfterMethod
public void shutdown() {
try (Session session = factory.openSession()) {
PurchaseOrder obj = this.findOrder(session, 10);
Transaction tx = session.beginTransaction();
session.delete(obj);
tx.commit();
}
factory.close();
}
@Test
public void testOrphanDelete() {
PurchaseOrder clone;
try (Session session = factory.openSession()) {
PurchaseOrder obj = this.findOrder(session, 10);
session.evict(obj);
clone = this.jsonClone(obj);
assertEquals(clone.getId(), 10); //passed
}
clone.removeItem(clone.getItems().get(0));
try (Session session = factory.openSession()) {
Transaction tx = session.beginTransaction();
assertEquals(clone.getItems().size(), 0); //passed
session.update(clone);
tx.commit();
}
try (Session session = factory.openSession()) {
PurchaseOrder obj = this.findOrder(session, 10);
//AssertionError: expected [0] but found [1]
assertEquals(obj.getItems().size(), 0);
}
}
private PurchaseOrder findOrder(Session session, int id) {
Query query = session.createQuery("from PurchaseOrder r "
+ "where r.id=:id");
query.setParameter("id", id);
return (PurchaseOrder) query.uniqueResult();
}
private PurchaseOrder jsonClone(PurchaseOrder order) {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
try {
String s = mapper.writeValueAsString(order);
return mapper.readValue(s, PurchaseOrder.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
PurchaseOder.java:
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(
generator=ObjectIdGenerators.PropertyGenerator.class,
property="id")
@Entity
@Access(AccessType.FIELD)
public class PurchaseOrder {
@Id
private int id;
private LocalDate issueDate;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "order")
private List<Item> items = new ArrayList<>();
PurchaseOrder(){}
public PurchaseOrder(int id, LocalDate issueDate) {
this.id = id;
this.issueDate = issueDate;
}
final int getId() {
return id;
}
public final LocalDate getIssueDate() {
return issueDate;
}
final List<Item> getItems() {
return items;
}
public void addItem(Item item) {
item.setOrder(this);
items.add(item);
}
public void removeItem(Item item) {
item.setOrder(null);
items.remove(item);
}
}
项目.java:
import java.math.BigDecimal;
import javax.persistence.*;
@Entity
@Access(AccessType.FIELD)
public class Item {
@Id
private int id;
private String name;
private BigDecimal price;
@ManyToOne(fetch = FetchType.EAGER)
private PurchaseOrder order;
Item(){}
Item(int id, String name, BigDecimal price) {
this.id = id;
this.name = name;
this.price = price;
}
final int getId() {
return id;
}
final String getName() {
return name;
}
final BigDecimal getPrice() {
return price;
}
final PurchaseOrder getOrder() {
return order;
}
final void setOrder(PurchaseOrder order) {
this.order = order;
}
}
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>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:D:/test</property>
<property name="connection.username">sa</property>
<property name="connection.password">sa</property>
<property name="hibernate.default_schema">PUBLIC</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
最后是我的版本号:
Java: 8 update181
hibernate :5.1.6
jackson :2.9.8
H2数据库:1.4.197
更新:问题仅针对孤儿移除。 Item child 的克隆更新或添加工作正常。因此,此测试没有失败:
@Test
public void testItemAdding() {
PurchaseOrder clone;
try (Session session = factory.openSession()) {
PurchaseOrder obj = this.findOrder(session, 10);
session.evict(obj);
clone = this.jsonClone(obj);
}
clone.setIssueDate(LocalDate.of(1999, 9, 9));
clone.addItem(new Item(2, "XYZ", new BigDecimal("182.50")));
try (Session session = factory.openSession()) {
Transaction tx = session.beginTransaction();
session.update(clone);
tx.commit();
}
try (Session session = factory.openSession()) {
PurchaseOrder obj = this.findOrder(session, 10);
assertEquals(obj.getIssueDate(), LocalDate.of(1999, 9, 9));
assertEquals(obj.getItems().size(), 2);
assertEquals(obj.getItems().get(1).getName(), "XYZ");
}
}
最佳答案
对象 clone
不受 jpa 管理,因为它处于 detached
状态。您需要先持久化它才能看到映射所做的更改。
关于java - Hibernate:orphanRemoval 不适用于克隆的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54848103/
什么是 hibernate 和n- hibernate ?我可以在 Visual Studio 2008 中使用它进行 C# Web 应用程序开发吗?请给我建议...我是 asp.net Web 应用
我有一个不系统地发生的异常(exception)。 我试图通过在每次迭代中刷新和清理 session 来解决此问题,但没有成功。 [quartzScheduler_Worker-7] ERROR jd
使用 Hibernate 在数据库中存储 IP 地址的最佳类型是什么? 我虽然是 Byte[] 或 String,但有没有更好的方法,或者你用什么? @Column(name = "range_fr
我正在尝试制定一个公式来选择用户个人资料的用户友好名称。它选择名字 + ' ' + 姓氏 如果其中至少有一个不为空且不为空(包含非空白字符),否则选择 短名称 (条件相同),最后,如果 短名称 为空或
在hibernate中,是否可以将鉴别器作为一个实体?例如,如果我将 Department 作为基类,将 AdminDepartment 和 ProcessingDepartment 作为子类。 De
我只想从表中获取一些列值。因此,我已经使用投影来实现这一目标。该代码有效,但我认为它无效。 我的问题是当我使用ProjectionsList并将标准条件列表设置为ArrayList时-Bulletin
你好: 我对 hibernate 缓存缓存的内容感到困惑。 从文档中,我知道 hibernate 中有缓存类型。 一级 :交易级别。 似乎要被 session 持久化的实体被缓存在这里。 二级缓存 :
我遇到了一个情况: save或update hibernate 的目标表中的某些数据 在目标表上有一个触发器,该触发器将在目标表的insert或update操作之前执行 由 hibernate 将此记
我有一个名为 Master_Info_tbl 的表。它是一个查询表: 这是该表的代码: @Entity @Table(name="MASTER_INFO_T") public class Code
我想知道如何在 Hibernate 查询语言中使用日期文字。我在我的 JPA 项目中做了如下操作(作为 Eclipselink 提供者)并且它工作正常。 SELECT m FROM Me m WHER
@Entity public class Troop { @OneToMany(mappedBy="troop") public Set getSoldiers() { ...
我正在尝试使用 hibernate 查询删除表 'user_role' 中的所有行。但每次我都会出错。有人可以帮我吗。 DaoImpl @Override public void deleteAll(
不是将数据库操作分散在四个 (osgi) 包中,而是在那里做略有不同的事情。我想创建一个负责所有持久性问题的(简单的)OSGi 包。我觉得这并不像听起来那么简单,因为“每个包都有独特的类加载器”。 因
这就是我使用生成器的方式: private Integer id; 我看到的行为是: 创建第一个对象 hibernate 分配 id = 1 删除该对象 关闭服务
对象级别的实体和值类型有什么区别。我知道实体将有一个 id 但值不会,但为什么我们需要不同的方法来映射实体与值类型? 这样做是为了让hibernate可以对值类型应用任何优化吗? 最佳答案 一个实体已
我正在使用 HibernateTemplate.findByCriteria 方法进行一些查询。现在我想在标准上创建一些 SQL 限制,比如 criteria.add(Restrictions.sql
所以我有以下代码: Query query = session.createQuery("from Weather"); List list = query.list();
如何使用Hibernate映射具有多个实体的 View ? 问候, 混沌 最佳答案 请参见Hibernate文档中第5.1.3节“类”,紧接在“Id”节之前: There is no differen
据我所知,Hibernate 有两种类型的实现 JPA的实现(2)(@Entity,@Table注解) 扩展到旧的(传统的) hibernate (没有 JPA),使用 HSQL 查询,没有注释 如果
我需要一个将条目存储为键值对的集合(因此我可以通过键查找值),但我需要一个允许多个值使用 hibernate 共享同一个键的集合 最佳答案 一个键具有多个值的映射称为多映射 - 在 Apache 公共
我是一名优秀的程序员,十分优秀!