在hibernate中,如果某个Entity的属性使用泛型,必须为其属性映射加上type属性。
public interface Entity<T> {
T getId();
}
public class BaseEntity<T> implements Entity<T> {
protected T id;
public T getId() {
return id;
}
}
public class Forum extends BaseEntity<Long> {
// ...
}
在泛型DAO经常会看到这样的代码。
Hibernate映射文件:
<class name="marlon.myforum.domain.model.Forum" table="FORUM">
<id name="id" column="ID" type="long">
<generator class="native" />
</id>
</class>
如果不加上type="long",运行时就会错:
org.hibernate.MappingException: identifier mapping has wrong number of columns: Forum type: object
at org.hibernate.mapping.RootClass.validate(RootClass.java:194)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1102)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1287)
从错误消息里可以看出hibernate认为id的type为"object",这是因为不指定type时,hibernate会自动根据属性的类型来决定,虽然在编译时id的类型为Long,但是由于泛型的Erase机制,编译之后类型信息就丢失了,通过反射得到id的类型为Object,这也就是为什么hibernate报错的原因。其实只要是通过反射来填充属性,都可能存在这种问题,比如在Web框架中,会将请求参数装载到一个bean中。假设如果id="abc",它仍然可以被填充到Forum的id属性中来,因为它的类型是一个Object,但是运行时通过forum.getId()时就会发生ClassCastException,这显然不是所期望的,这时id实际是一个String,现在需要换成Long。为了避免这种问题,对于上面的例子,可以将BaseEntity不声明为泛型,而直接容纳一个类型为Long的id,这样虽然没有将BaseEntity灵活,对ID其它类型的Entity需要直接实现Entity接口,但是却避免了使用泛型BaseEntity的缺点。
public class BaseEntity implements Entity<Long> {
protected Long id;
public Long getId() {
return id;
}
}
由此可见,用泛型也是需要慎重考虑的,虽然它能够带来编译时类型安全,但是不能忘记了编译后就是一个裸的Object(在没有指定限定符时),这在需要用反射中填充属性时尤其要注意,而现在大多数的Java框架又广泛的运用了此。
分享到:
相关推荐
1.实现泛型的Hibernate 2.Spring+Hibernate搭建 3.maven构建工程
基于hibernate5 泛型Dao实例,下载后改一下数据库 配置直接可以用
WCF服务的操作方法中实现T GetEntity(int id) where T: EntityBase
利用泛型编写的hibernate basedao,涵盖几乎所有数据库操作方法,需导入spring相关jar包
本文讨论泛型使用的一般问题,比如为什么要使用泛型、泛型的编写方法、泛型中数据类型的约束、泛型中静态成员使用要注意的问题、泛型中方法重载的问、泛型方法等,通过这些使我们可以大致了解泛型并掌握泛型的一般...
通用道在 JPA/HIbernate/Spring 环境中使用泛型提供 DAO API,因此它可以与此类架构中的任何 Hibernate POJO 一起使用,而无需为每个域类创建专用的数据访问接口。 Maven 依赖项: <dependency> <groupId>org....
座位数可以在系统中指定 点击座位可购买不同类型的电影票 使用简单工厂模式创建不同类型的电影票 使用多态实现不同类型电影票的价格计算 使用接口实现电影票的打印 使用序列化和反序列化实现销售情况的保存和读取
这是自己用在不使用泛型的基础上,用c++实现的一个vector功能,经过10万测试考验,没问题可用,如果大家有更好的建议和意见,还请指出,有不对的地方也请指出,大家一起进步,学习,加油。
java 使用泛型,优化重复多余代码.
Struts2 Spring3 Hibernate 注解功能 DAO 泛型 通用分页
TypeScript 完全支持泛型,以此将类型安全性引入到接受参数和返回值的组件中,这些参数和返回值的类型,在稍后的代码中使用之前是不确定的。 在今天的内容中,我们将尝试 TypeScript 泛型的真实示例,并探索它们...
C#泛型集合使用实例C#泛型集合使用实例C#泛型集合使用实例
关于如何在C#中使用泛型,希望对大家有帮助
Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复...
java 泛型方法使用示例 java 泛型方法使用示例 java 泛型方法使用示例
在.NET FCL为我们提供了很多...结论:如果在C#2.0版本以上,尽量使用泛型集合类,而不使用非泛型集合类。因为,1. 泛型编程是从c#2.0开始才被.net支持的。2.泛型集合在性能和类型安全方面优于非泛型集 合。 。。。。
一个用springmvc+hibernate+spring maven实现的增、删、改、查的例子
泛型,无论在Java中还是在C#中,应用都很广泛,可以解决很多关于类型的问题
Hibernate泛型DAO及使用方法.
泛型类、泛型方法、泛型接口、泛型委托 泛型类、泛型方法、泛型接口、泛型委托