在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框架又广泛的运用了此。
分享到:
相关推荐
在传统的Hibernate使用中,针对每个实体类,我们都需要创建一个对应的Dao(Data Access Object)接口及其实现类,这无疑增加了大量重复的代码。泛型Dao的出现,就是为了解决这个问题,它允许开发者通过泛型来定义一...
在Java开发领域,尤其在企业级应用开发中,Hibernate框架因其强大的对象关系映射(ORM)能力而受到广泛欢迎。泛型Hibernate是利用Java泛型特性对Hibernate进行封装的一种方式,目的是为了提供更简洁、灵活且易于维护...
泛型是Java SE 5.0引入的新特性,它允许在类、接口和方法中使用类型参数,从而实现更强大的类型检查和减少类型转换的冗余。 1. 泛型BaseDAO:`GenericBaseDao.java`和`GenericBaseDaoInter.java` 泛型BaseDAO的主要...
在Hibernate4及以后的版本中,注解成为主要的映射方式,如`@Entity`标识实体类,`@Table`指定对应数据库表,`@Id`定义主键,`@GeneratedValue`自动生成主键值,以及`@Column`定义字段映射等。 在...
基于泛型的通用Dao接口是指使用泛型来实现数据访问对象(DAO)的接口,主要是在使用 Hibernate 或 JPA 时使用。泛型可以使得DAO接口更灵活、更通用。 泛型Dao接口的优点: 1. 耦合性低:泛型Dao接口可以与不同的...
在Hibernate中,我们可以使用HibernateTemplate或SessionFactory来实现这个泛型DAO。例如: ```java public abstract class HibernateGenericDao, ID extends Serializable> implements GenericDao, ID> { ...
`DaoUtil`类初始化了一个`SessionFactory`实例,并提供了一个获取`Session`的静态方法,方便在DAO实现类中使用。 总的来说,"Hibernate泛型DAO接口,大部分通用都已包括"意味着我们已经定义了一套完整的、适用于多...
- 在这个例子中,Hibernate用于建立Java对象(Entity)与数据库表之间的映射关系,通过Session接口进行数据的CRUD操作。例如,使用`SessionFactory`创建`Session`,然后调用`save()`, `get()`, `update()` 和 `...
在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者使用面向对象的方式来操作数据库,而无需关心底层SQL语句的编写。然而,为了提高代码的复用性和可维护性,通常会设计一个通用DAO...
本文档主要探讨了如何在Spring+Hibernate环境中创建和使用泛型DAO。 首先,我们来看一下泛型DAO接口的定义。在`com.th.huz`包下,定义了一个名为`GenericDao`的接口,它有两个泛型参数:`T`代表要操作的实体类,`PK...
在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者用面向对象的方式处理数据库操作。在大型项目中,为了提高代码的复用性和可维护性,通常会采用DAO(数据访问对象)模式来隔离业务...
本篇文章将深入探讨一个使用Spring注解和Hibernate实现的泛型DAO设计,以提高代码的复用性和可维护性。 首先,`HibernateBaseDao.java`是基础的Hibernate DAO类,它提供了对Hibernate操作的基本封装。这个类通常会...
在Java开发中,尤其是涉及到企业级应用,Spring和Hibernate框架的结合使用是非常常见的。而`Hibernate泛型DAO`则是为了减少代码重复性,提高代码复用性和可维护性的一种设计模式。本文将深入探讨`Hibernate泛型DAO`...
在解压后,我们可以找到具体的`GenericDao.java`或相关的接口及实现类,通过阅读这些代码,可以深入理解如何在Spring和Hibernate环境中使用泛型来设计数据访问层。 总的来说,这个资源提供了一个使用泛型和主流Java...
在Java开发中,特别是使用Spring+Hibernate框架时,泛型DAO(Data Access Object)是常见的设计模式,它提供了对数据库操作的一般化接口,以提高代码的重用性和可维护性。本文将探讨如何设计和使用泛型Hibernate DAO...
Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复...
在Struts2+Hibernate+Spring的集成中,泛型DAO扮演着重要的角色,它使得DAO层对所有实体类的操作变得统一和规范。 首先,让我们详细了解一下Struts2。Struts2是基于拦截器的MVC框架,它提供了强大的动作映射、结果...
例如,它可能会定义一个Hibernate的SessionFactory或Data Source,这样就可以在泛型DAO中使用这些配置来操作数据库。 总之,泛型DAO是Java开发中一个非常实用的设计模式,它通过泛型提升了代码的复用性,并且与ORM...
本篇将详细介绍如何利用泛型和Hibernate ORM技术实现一个通用的帮助类,以便在处理相同实体类属性的新增和修改时,通过同一接口进行操作。 首先,泛型是Java语言的一个重要特性,它允许在定义类、接口和方法时使用...