hibernate 通用 dao 重载 removeById
Posted
技术标签:
【中文标题】hibernate 通用 dao 重载 removeById【英文标题】:hibernate generic dao overloading removeById 【发布时间】:2016-07-23 00:56:50 【问题描述】:我在我的 java 项目中实现休眠 ORM。 我从github 下载了源代码 我已经编译了示例中包含的 hibernate-maven-web。 现在让我们假设我想在其中一个实现中重载方法 例如 CitizenDAOImpl.java 在我进行更改之前,它看起来像这样。
package sample.googlecode.genericdao.oldworld.dao;
import org.springframework.stereotype.Repository;
import sample.googlecode.genericdao.oldworld.model.Citizen;
/**
* <p>
* This is the implementation of the Citizen DAO. You can see that we don't
* actually have to implement anything, it is all inherited from GenericDAOImpl
* through BaseDAO. We just specify the entity type (Citizen) and its identifier
* type (Long).
*
* <p>
* The @Repository allows Spring to recognize this as a managed component (so we
* don't need to specify it in XML) and also tells spring to do DAO exception
* translation to the Spring exception hierarchy.
*
* @author dwolverton
*
*/
@Repository
public class CitizenDAOImpl extends BaseDAO<Citizen, Long> implements CitizenDAO
我所做的只是重写将调用超类的 removeById。 稍后我打算添加一些加密功能,所以 id 都会被打乱。
package sample.googlecode.genericdao.oldworld.dao;
import org.springframework.stereotype.Repository;
import sample.googlecode.genericdao.oldworld.model.Citizen;
/**
* <p>
* This is the implementation of the Citizen DAO. You can see that we don't
* actually have to implement anything, it is all inherited from GenericDAOImpl
* through BaseDAO. We just specify the entity type (Citizen) and its identifier
* type (Long).
*
* <p>
* The @Repository allows Spring to recognize this as a managed component (so we
* don't need to specify it in XML) and also tells spring to do DAO exception
* translation to the Spring exception hierarchy.
*
* @author dwolverton
*
*/
@Repository
public class CitizenDAOImpl extends BaseDAO<Citizen, Long> implements CitizenDAO
@Override
public boolean removeById(java.io.Serializable id)
return super.removeById(id);
当我运行 mvn clean install 时出现错误
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.
1:compile (default-compile) on project hibernate-maven-web: Compilation failure
[ERROR] /C:/Dev/spike/hibernate-maven-web/src/main/java/sample/googlecode/generi
cdao/oldworld/dao/CitizenDAOImpl.java:[26,24] name ***: removeById(java.io.Ser
ializable) in sample.googlecode.genericdao.oldworld.dao.CitizenDAOImpl and remov
eById(ID) in com.googlecode.genericdao.dao.hibernate.GenericDAO have the same er
asure, yet neither overrides the other
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e swit
ch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please rea
d the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureExc
eption
我知道它的模糊调用以及 BaseDAO 和 CitizenDAO 在某些时候确实继承了 GenericADO。 在这种情况下有什么好的解决方案? 谢谢
【问题讨论】:
【参考方案1】:实际上你的方法并没有覆盖超类方法,你应该使用
Long id
而不是 Serializable id
作为参数使其被覆盖。
超类是一个有界泛型类,因为它对 ID 的泛型类型有ID extends Serializable
限制。请注意,通用信息不会存储在运行时中,并且会被删除。这只是一个编译时间信息。详情请见https://docs.oracle.com/javase/tutorial/java/generics/erasure.html。
这里您的自定义方法不会覆盖超类方法,而且,这两个方法都是通用的并且具有相同的擦除。所以在运行时,在擦除之后,这些方法将具有相同的签名,JVM 会混淆要调用哪一个。这就是编译器因错误而失败的原因。
【讨论】:
感谢您的评论。我有点来自 C++ 世界,所以我会假设某种虚拟继承来在运行时手动选择方法。在这种情况下,我们在 Java 中做什么? 为什么你需要Serializable
在这里输入ID?根据类定义,它必须是Long
。如果您需要其他类型的 ID,请考虑创建 extends BaseDAO<Citizen, Serializable>
的新类。如果您需要在当前类中接受Serializable
ID 的方法,您可以选择另一个方法名称(在这种情况下不要忘记删除@Override
注释)。但是以这种方式,我怀疑该方法的必要性,因为它非常脆弱。如果您传递与 Long
不同的内容,您将不得不手动转换类型,并且将在运行时捕获 ClassCastException
。
我改成 Long 了,问题依旧。
完全相同的错误?不敢相信,这很奇怪..你能附上更新的代码和错误信息吗?以上是关于hibernate 通用 dao 重载 removeById的主要内容,如果未能解决你的问题,请参考以下文章
Spring 3,带有通用 DAO 的 Hibernate 4 AutoWired sessionFactory
在通用 DAO 中使用 Hibernate 调用存储过程的最佳方法是啥?