首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Hibernate 保存實體時自動生成字段值:使用 Interceptor 實現 code1 自動賦值

     編輯:程式設計綜合問答

需求

實體 E 包含 id(自增)、name(表單輸入)、code1(需在保存時自動生成)。希望在 session.save(e) 時自動填充 code1,不在表單/Controller 處理。

方案:Hibernate Interceptor

實現 org.hibernate.Interceptor 接口,重寫 onSave 方法:

public class CodeGeneratorInterceptor extends EmptyInterceptor {
    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        if (entity instanceof E) {
            E e = (E) entity;
            // 假設 code1 是第 3 個屬性(索引 2)
            for (int i = 0; i < propertyNames.length; i++) {
                if ("code1".equals(propertyNames[i])) {
                    state[i] = generateCode1(); // 你的生成邏輯
                    return true; // 表示 state 已修改
                }
            }
        }
        return false;
    }
    
    private String generateCode1() {
        // 你的生成算法,如 UUID、雪花算法、業務編碼規則等
        return "CODE-" + System.currentTimeMillis();
    }
}

註冊與使用

// 方式 1:SessionFactory 級別(全局生效)
Configuration cfg = new Configuration();
cfg.setInterceptor(new CodeGeneratorInterceptor());
SessionFactory sf = cfg.buildSessionFactory();

// 方式 2:單次 Session 級別(推薦,線程安全)
Session session = sessionFactory.openSession(new CodeGeneratorInterceptor());
Transaction tx = session.beginTransaction();
session.save(e);
tx.commit();
session.close();

優勢

  • 關注點分離:生成邏輯集中在 Interceptor,不污染 Entity/Service/Controller;
  • 自動生效:所有保存路徑(save、persist、merge、Cascade)均觸發;
  • 可訪問完整狀態:state 數組包含所有將持久化的屬性值,可根據其他字段計算。

替代方案對比

方案優點缺點
Entity @PrePersistJPA 標準,簡單無法訪問 Session/事務上下文,生成邏輯受限
Service 手動設置直觀可控易忘、代碼分散、耦合業務邏輯
Database Trigger數據庫級保證跨庫遷移困難、調試難、業務邏輯下沉
Interceptor (推薦)框架級、靈活、可訪問上下文需理解 Hibernate 內部機制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved