`
Ryan_Wang
  • 浏览: 4765 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类

修改Hibernate源码实现建表时字段和Entity里定义的fields顺序一致

阅读更多
Hibernate(至截稿时最新版本为4.1.3.Final)自动建表的表字段顺序总是随机的,之前我们总是自己写语句建好表,再使用Hibernate进行增删改查。始终是有点不方便。
最近看了下源码,发现很多地方都是使用LinkedHashMap或者是List来传输Entity里面的fields,觉得Hibernate应该是考虑到使用Entity里面定义的fields的顺序来实现建表语句里的表字段顺序的。
于是一步步跟踪下去,终于在一个地方发现了一个问题:org.hibernate.cfg.PropertyContainer在取fields的时候是使用TreeMap来保存的,于是试着改了下,将这个里面的所有TreeMap改成了LinkedHashMap,编译通过,打包,测试。
终于,我们期待已久的结果出来了:建表语句里面的字段顺序和Entity里面的fields的顺序一致了。

以下附上源码和修改后的代码:
源码:

private final TreeMap<String, XProperty> fieldAccessMap;

private final TreeMap<String, XProperty> propertyAccessMap;

private TreeMap<String, XProperty> initProperties(AccessType access) {
if ( !( AccessType.PROPERTY.equals( access ) || AccessType.FIELD.equals( access ) ) ) {
throw new IllegalArgumentException( "Access type has to be AccessType.FIELD or AccessType.Property" );
}

// 其实通过以下注释也可以发现是Hibernate自己的一个失误
//order so that property are used in the same order when binding native query
TreeMap<String, XProperty> propertiesMap = new TreeMap<String, XProperty>();
List<XProperty> properties = xClass.getDeclaredProperties( access.getType() );
for ( XProperty property : properties ) {
if ( mustBeSkipped( property ) ) {
continue;
}
propertiesMap.put( property.getName(), property );
}
return propertiesMap;
}

修改后的代码

private final LinkedHashMap<String, XProperty> fieldAccessMap;

private final LinkedHashMap<String, XProperty> propertyAccessMap;

private LinkedHashMap<String, XProperty> initProperties(AccessType access) {
if ( !( AccessType.PROPERTY.equals( access ) || AccessType.FIELD.equals( access ) ) ) {
throw new IllegalArgumentException( "Access type has to be AccessType.FIELD or AccessType.Property" );
}

//order so that property are used in the same order when binding native query
LinkedHashMap<String, XProperty> propertiesMap = new LinkedHashMap<String, XProperty>();
List<XProperty> properties = xClass.getDeclaredProperties( access.getType() );
for ( XProperty property : properties ) {
if ( mustBeSkipped( property ) ) {
continue;
}
propertiesMap.put( property.getName(), property );
}
return propertiesMap;
}

PS:通过以下代码可以测试建表时的语句:
public static void main(String[] args) {
    Configuration cfg = new Configuration().configure();
    SchemaExport export = new SchemaExport(cfg);
    export.create(true, true);
}
建表语句会输出到控制台,对比之前未作修改时的语句,可以看出差别。
修改后数据库(MySQL 5.5.24)的对应表字段顺序和Entity定义的fields顺序一致。

我已将此改动向Hibernate开发组提出,希望以后会在官方版本里实现此改动。
链接如下:
https://forum.hibernate.org/viewtopic.php?f=1&t=1015920
分享到:
评论
1 楼 Ryan_Wang 2017-01-12  
https://hibernate.atlassian.net/browse/HHH-11386

相关推荐

    解决 Springboot Jpa 自动创建表 和字段乱序问题[凤凰小哥哥]

    产生原因:因为使用 jpa 自动创建表的时候,采用的是TreeMap的,我们要变成LinkedHashMap ...解决方案:在项目下java文件夹下创建包名为: org.hibernate.cfg ,创建类: PropertyContainer [包名,类名一定要相同哦]

    Hibernate动态建表

    "Hibernate动态建表"指的是在应用运行时根据实体类自动生成对应的数据库表结构,这种特性在开发过程中特别有用,尤其是当数据模型频繁变化或者需要快速原型设计时。 **动态表映射原理** Hibernate的动态建表功能...

    hibernate源码 直接使用

    通过理解并熟练运用这些核心概念和步骤,我们可以直接在项目中有效地使用Hibernate源码,实现高效的数据持久化和复杂的关联关系管理。对于初学者而言,理解并实践这些知识点是掌握Hibernate的关键。

    JPA注解 和hibernate 建表

    JPA注解和Hibernate建表 一、JPA概述 Java Persistence API(JPA)是Sun官方提出的Java持久化规范,它只是一个规范不是一个产品。JPA的主要目标是提供一种简洁、易用的方式来访问、操作和管理Java应用程序中的数据...

    Hibernate建表用到的jar包

    在使用Hibernate进行数据库建表时,需要依赖一系列的jar包,这些jar包包含了Hibernate的核心功能和其他必要的库。下面将详细介绍这些jar包及其在Hibernate建表中的作用。 1. **hibernate-core.jar**:这是Hibernate...

    传智播客hibernate源码

    - `hibernate_080914`: 直接与Hibernate相关的源码或教程材料,可能涵盖Hibernate的核心概念和用法。 通过研究这些文件,学习者可以深入了解Hibernate的工作原理,提升数据库操作的技能,并了解如何在实际项目中...

    Hibernate源码解析(二)

    在本篇《Hibernate源码解析(二)》中,我们将深入探讨Hibernate这一强大的Java对象关系映射(ORM)框架的内部工作原理。这篇博客旨在帮助开发者更好地理解Hibernate的核心机制,以便于更高效地利用它来处理数据库...

    精通hibernate源码ch2

    在深入探讨Hibernate源码之前,我们首先需要理解什么是对象持久化技术。对象持久化是将内存中的对象状态保存到持久存储介质(如数据库)中,以便在后续的程序运行中可以恢复这些对象的状态。它解决了应用程序中的...

    java实体类字段自定义-数据库字段和程序实体类属性不一致解决方案.docx

    Java 实体类字段自定义-数据库字段和程序实体类属性不一致解决方案 Java 实体类字段自定义是指在 Java 开发中,实体类的字段与数据库表的字段不一致的问题。这种情况下,需要实现实体类字段的自定义,以便与数据库...

    hibernate源码

    3. **实体类和映射文件**:每个Java实体类都对应一个数据库表,使用注解(如`@Entity`、`@Table`等)或XML文件(`*.hbm.xml`)来定义映射规则。属性映射到字段,关系映射到外键,使得对象可以直接存取数据库。 4. *...

    hibernate源码release-4.1.4.Final版

    Hibernate通过@Entity注解标记Java类为数据库表的映射,@Table定义表名,@Id指定主键,@GeneratedValue管理主键生成策略。其他如@Column、@OneToMany、@ManyToOne等注解则用于定义字段映射关系。 四、缓存机制 ...

    Hibernate源码

    找到一手资料不易,这份源码对于研究和学习Hibernate的内部实现具有很高的价值。 【标签】中的"hibernate"是本次主题的核心,它是一个强大的ORM框架,通过提供对象-关系映射工具,简化了Java应用与数据库之间的交互...

    hibernate源码的学习

    总结,学习Hibernate源码有助于我们理解ORM的底层实现,掌握对象关系映射的精髓,从而在实际项目中更好地利用Hibernate提升开发效率和代码质量。通过对"hibernate-one2many"的分析,我们可以深入研究和实践一对一和...

    传智播客hibernate源码.rar

    通过深入学习和理解Hibernate源码,你可以了解到其内部的工作原理,这将使你在解决实际问题时更具针对性和效率。结合“hibernatedao_080914”、“Jpa_0914”和“hibernate_080914”中的示例和实践,相信你的...

    hibernate5.1.10源码包

    例如,`@Entity`注解用于标记一个Java类为实体,`@Table`注解指定对应的数据库表,`@Id`注解定义主键字段。此外,还有`@GeneratedValue`用于自动生成主键值。 2. 事务处理:Hibernate支持JTA(Java Transaction API...

    精通Hibernate源码

    《精通Hibernate源码》是孙卫琴先生的一部深度解析Hibernate框架源码的著作,旨在帮助读者深入理解这个流行的Java持久层框架的工作原理。通过学习本书,开发者可以提升对ORM(Object-Relational Mapping)技术的理解,...

    自动在数据库中建成表(Hibernate)

    除了自动建表,Hibernate还提供了丰富的查询语言HQL(Hibernate Query Language)和Criteria API,使得查询数据库更加方便。HQL是面向对象的查询语言,而Criteria API提供了一种更动态、类型安全的方式来构建查询。 ...

    hibernate-3.5.6 源码

    这个资源是Hibernate 3.5.6版本的源码,对于理解ORM框架的内部工作原理、学习数据库交互以及深入研究Hibernate的实现机制非常有帮助。 1. **对象关系映射(ORM)**:ORM是Hibernate的核心特性,它允许开发者用Java...

Global site tag (gtag.js) - Google Analytics