`
power1128
  • 浏览: 24369 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

Hibernate load方法引起的java equal方法失效的问题

    博客分类:
  • java
阅读更多

Hibernate load方法引起的java equal方法失效的问题

前段时间在一个业务代码中,发现java对象的equal方法无论如何不起作用,判断结果始终是不相等。最后仔细排查,发现原来是hibernate的load方法间接导致了该问题的发生。

众所周知,Hibernate根据id加载对象有两套方法。一套是get,一套是load。

如果不了解这两个方法的区别,很可能导致陷入一些意想不到的陷阱。

通过查阅官方API,我简单总结下它们最主要的两个区别:

  1. 在不存在以该id缓存的对象时,get返回持久类的一个对象,load返回代理类的一个对象;
  2. 当根据指定id在缓存和数据库中都无法找到相应对象时,get返回null,而load抛出异常。但该异常可能在调用某个非id字段的access method时才触发;

当load返回代理对象,并且我们使用该代理对象与实际业务对象进行比较操作时,就会出现问题。

出现的问题可能也有两种:

  1. 由于equal方法要判断被比较的两个对象的类名,因此此时会返回false;
  2. 如果我们直接用a.id.equals(b.id)——其中a是业务对象,b是代理对象,这里也会返回false。因为代理对象的所有属性都是null!

如果我们只能在equals方法层面解决问题,那么对于问题1,我们可能只能去掉对class是否相同的判断。或者增加排除代理类的情况。对于问题2,尽量使用getId替代直接的属性访问。

我推荐的解决方法是:尽量使用get方式。即使可能存在返回null的情况。如果返回null是不允许的,那么使用断言抛出异常应该也是很简单的事情。

0
2
分享到:
评论
1 楼 spiniper 2013-11-20  
如果要为此类似操作,需要使用getId()的方式来比较,这样完成hibernate懒加载对象的初次加载再进行比对,就不会出现懒加载对象还未加载,内部属性为null返回false的情况。

另外,对于Class模板的比较,对于hibernate的懒加载代理对象是不合适的,除非你取消懒加载,否则Class比对肯定是false。我曾经也想过这个问题,后来找到一个相对而言变通的方法,就是不用Class比对,而是使用与Class同级别的注解的比对,如果你使用hibernate注解,那么肯定每个对象都有一个@Entity的注解头,当然这个头可以为空,不过规定要求每个实体必须给一个名字@Entity(name="className"),这样对它进行比较,就会正确。 当然,如果你使用的是hiberate配置文件的方式,就要另想办法了,例如自己 写个注解接口。

相关推荐

    3 Java中关于==和equal的区别 以及equals()方法重写

    Java 中关于 == 和 equal 的区别 及其 equals() 方法重写 Java 语言是 Sun 公司的开发成果,其主要特点是可以执行强,与平台的无关性使其实用性更强。但是 Java 中的 == 与 equal 是有区别的。 == 操作符是 Java ...

    java 字符串中文判断

    在Java编程语言中,处理字符串是非常常见的操作,尤其是在涉及到文本分析和处理的场景。本文将深入探讨如何在Java中进行中文字符的判断和计数,这主要基于Java的Unicode编码特性以及字符集的理解。 首先,我们需要...

    equal与==区别

    在Java编程语言中,`equal`方法和`==`操作符都是用来比较对象之间是否相等的工具,但它们之间存在重要的差异。本文将从三个方面进行详细的对比分析:字符串的比较、非字符串对象的比较以及基本数据类型的比较。 ###...

    Hibernate的使用例子代码

    **Hibernate 是一个强大的Java持久化框架,用于管理数据库操作,简化了对象关系映射(ORM)的过程。在Java开发中,Hibernate 提供了一种抽象层,使得开发者可以使用面向对象的方式来处理数据库,而无需直接编写SQL...

    JAVA常用类和方法

    ### JAVA常用类和方法知识点详解 #### 一、字符串处理 **1. 获取字符串长度** - **方法**: `length()` - **用途**: 返回字符串的长度。 - **示例**: ```java String str = "Hello"; int len = str.length...

    java hibernate 实例

    Java Hibernate 是一个强大的对象关系映射(ORM)框架,它为Java开发者提供了便捷的数据持久化方式,使得在Java应用程序中操作数据库变得更加简单。本实例旨在介绍如何使用Hibernate进行基本的数据操作,包括自动...

    Hibernate-API打包

    Hibernate是一个强大的Java持久化框架,它简化了数据库操作,使得开发者可以更加专注于业务逻辑,而非底层的SQL语法。本篇文章将围绕“Hibernate-API打包”这一主题,详细解析Hibernate的核心API,并探讨如何在实际...

    java常用方法大全

    ### Java常用方法详解 #### 字符串操作 **1. 获取字符串长度** - **方法名**: `length()` - **功能**: 返回字符串中字符的数量。 - **示例**: 如果有一个字符串 `"Hello"`,那么 `length()` 的结果将是 `5`。 ...

    java-leetcode题解之Equal Rational Numbers.java

    java java_leetcode题解之Equal Rational Numbers.java

    4种方法在java中,对日期时间的比较.docx

    本文将详细介绍四种在Java中比较日期时间的方法,并通过示例代码进行解释。 1. `Date.compareTo()` 方法 `java.util.Date` 类提供了一个 `compareTo()` 方法,该方法用于比较两个日期对象的顺序。它遵循以下规则: ...

    java-leetcode题解之Partition Equal Subset Sum.java

    java java_leetcode题解之Partition Equal Subset Sum.java

    java-leetcode题解之Get Equal Substrings Within Budget.java

    java java_leetcode题解之Get Equal Substrings Within Budget.java

    JAVA代码、方法、运算符大全

    本资源包"JAVA代码、方法、运算符大全"是针对Java初学者和进阶者的一份宝贵资料,它涵盖了Java编程中的核心元素:代码、方法和运算符。 一、Java代码 Java代码是实现特定功能的指令集合,它由类(Class)、方法...

    Hibernate的高级查询

    在Java的持久化框架中,Hibernate是一个非常重要的工具,它为开发者提供了强大的对象关系映射(ORM)功能,使得在数据库操作上可以采用面向对象的方式。当我们需要进行更复杂的数据库查询时,Hibernate提供了丰富的...

    Hibernate查询映射试验

    在Java世界中,Hibernate是一个非常流行的持久化框架,它简化了数据库操作,使得开发者可以更加专注于业务逻辑,而不是底层的数据访问细节。本实践项目“Hibernate查询映射试验”旨在通过一系列示例帮助开发者掌握...

    JAVA Integer == equal 比较 doc 比较大小 是否相等

    本文将深入探讨 Java 中的 Integer 比较,了解为什么使用 "==" 运算符可能会出错,并解释如何正确地使用 equals() 方法来比较 Integer 对象。 Java 中的 Integer 对象 在 Java 中,Integer 是一个不可变的类,它...

    java-leetcode题解之Partition to K Equal Sum Subsets.java

    java java_leetcode题解之Partition to K Equal Sum Subsets.java

    java中==与equal()区别

    Java 中的 == 和 equals() 是两个不同的比较方法,它们之间有着很大的区别。== 操作符专门用来比较两个变量的值是否相等,也就是比较变量所对应的内存中所存储的数值是否相同。用于比较两个基本类型的数据或两个引用...

    Java字符串比较方法equals的空指针异常的解决

    在上面的代码中,equal1方法将抛出java.lang.NullPointerException异常,而equal2方法没有。这是因为,在equal1方法中,i为空时,调用i.equals(j)将抛出空指针异常,而在equal2方法中,j为空时,调用j.equals(i)不会...

    java 怎么去校验时间

    - 比较时间:`isBefore()`, `isAfter()` 和 `isEqual()` 方法可以用来比较两个`LocalTime`对象的先后顺序。 - 验证时间范围:你可以通过比较`LocalTime`对象与预设的开始和结束时间来确保时间在指定范围内。 2. *...

Global site tag (gtag.js) - Google Analytics