当前位置:首页 > 行业动态 > 正文

Hibernate初体验及简单错误排除

Hibernate初体验需配置环境、映射实体、执行CRUD操作,常见错误如配置、映射、Session问题,可通过查日志、

Hibernate初体验及简单错误排除

Hibernate简介与核心概念

Hibernate是一个基于Java的对象关系映射(ORM)框架,它通过将Java对象与数据库表建立映射关系,简化了数据库操作,开发者无需直接编写SQL语句,而是通过操作对象实现数据的增删改查,其核心概念包括:

概念 说明
Session 类似于JDBC的Connection,用于管理一次数据库对话,支持事务操作。
SessionFactory 线程安全的工厂类,用于创建Session实例,通常应用中只需创建一个。
Entity 标注为@Entity的Java类,与数据库表一一对应。
Mapping 通过XML或注解定义对象与表的映射关系(如字段与列的对应)。
HQL(Hibernate Query Language) 面向对象的查询语言,语法类似SQL,但操作对象而非表。

环境搭建与基础配置

  1. 添加依赖
    以Maven项目为例,需在pom.xml中引入Hibernate核心依赖:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.6.15.Final</version>
    </dependency>
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>javax.persistence-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.30</version>
    </dependency>
  2. 配置hibernate.cfg.xml
    src/main/resources目录下创建配置文件:

    <hibernate-configuration>
        <session-factory>
            <!-数据库连接 -->
            <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testdb</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password">123456</property>
            <!-方言与自动建表 -->
            <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
            <property name="hibernate.hbm2ddl.auto">update</property>
            <!-显示SQL日志 -->
            <property name="hibernate.show_sql">true</property>
            <property name="hibernate.format_sql">true</property>
            <!-映射实体类 -->
            <mapping class="com.example.entity.User"/>
        </session-factory>
    </hibernate-configuration>
  3. 创建实体类与映射
    定义一个User实体:

    Hibernate初体验及简单错误排除  第1张

    @Entity
    @Table(name = "t_user") // 指定表名(可选)
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键
        private Long id;
        @Column(name = "username", length = 50) // 指定列名与长度
        private String username;
        @Column(name = "age")
        private Integer age;
        // Getter/Setter省略
    }

基础CRUD操作

  1. 初始化SessionFactory

    private static SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
  2. 保存数据(Insert)

    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    User user = new User();
    user.setUsername("John");
    user.setAge(25);
    session.save(user); // 生成INSERT语句
    tx.commit();
    session.close();
  3. 查询数据(Select)

    • HQL查询
      String hql = "FROM User WHERE age > :age";
      Query<User> query = session.createQuery(hql, User.class);
      query.setParameter("age", 20);
      List<User> users = query.list();
    • Criteria查询
      CriteriaBuilder cb = session.getCriteriaBuilder();
      CriteriaQuery<User> cq = cb.createQuery(User.class);
      Root<User> root = cq.from(User.class);
      cq.select(root).where(cb.greaterThan(root.get("age"), 20));
      List<User> users = session.createQuery(cq).getResultList();
  4. 更新与删除(Update/Delete)

    User user = session.get(User.class, 1L); // 查询主键为1的记录
    user.setAge(30);
    session.update(user); // 生成UPDATE语句
    session.delete(user); // 生成DELETE语句

常见错误与解决方案

错误现象 可能原因 解决方案
Could not find a specification for + entityClass.getName() 未在配置文件中声明实体类映射 hibernate.cfg.xml中添加<mapping class="com.example.entity.User"/>
No CurrentSessionContext available! Session未绑定到线程或事务范围 启用current_session_context_class配置:<property name="hibernate.current_session_context_class">thread</property>
Identifier of an instance of ... was altered from ... to ... 主键字段被修改 确保实体类的@Id字段不会被业务逻辑修改,或手动维护主键一致性
NonUniqueObjectException 重复插入相同主键的实体 检查@GeneratedValue策略或手动设置唯一主键
LazyInitializationException Session关闭后访问懒加载属性 在事务范围内操作,或启用hibernate.enable_lazy_load_no_trans=true(慎用)

实战案例:整合Spring(可选)

若结合Spring框架,可通过LocalSessionFactoryBean管理SessionFactory,并通过@Transactional注解简化事务控制。

@Service
public class UserService {
    @Autowired
    private SessionFactory sessionFactory;
    public void saveUser(User user) {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        session.save(user);
        tx.commit();
        session.close();
    }
}

相关问答FAQs

Q1:为什么执行session.save(user)后,数据库未插入数据?
A1:可能原因包括:

  1. 事务未提交(需调用tx.commit());
  2. hibernate.hbm2ddl.auto配置为validatenone,且表不存在;
  3. 实体类未正确映射(如缺少@Entity注解或主键未定义)。

Q2:如何避免NonUniqueObjectException
A2:常见场景是多次合并同一持久化对象,解决方案:

  1. 确保每个实体有唯一主键;
  2. 避免重复调用session.save(user)session.merge(user)
  3. 使用session.saveOrUpdate(user)统一处理新增
0