You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Hibernate ORM的HQL实现报错排查:空指针异常与Autowired静态字段注入问题

Fixing Your Hibernate/Spring Boot Issues

Let's tackle each of your problems one by one, starting with the most critical injection errors and NPE, then moving to the broken HQL save logic.


1. Resolve @Autowired Static Field Error & NullPointerException

Root Causes

  • Spring doesn’t support @Autowired on static fields: Static fields belong to the class, not an instance of the bean, so Spring can’t inject dependencies into them. Your hibernateUtilModel static field is triggering the first error.
  • Syntax typo in HibernateUtilModel: The @Value for ddl-auto has a missing opening brace ($spring.jpa.hibernate.ddl-auto} instead of ${spring.jpa.hibernate.ddl-auto}), so this property fails to inject correctly.
  • Uninitialized dependency in static method: Your getSessionFactory() static method tries to use an uninitialized hibernateUtilModel, leading to the NullPointerException.

Fixes

Step 1: Correct the @Value Typo in HibernateUtilModel

@Data
@AllArgsConstructor
@NoArgsConstructor
@Service
public class HibernateUtilModel {
    // ... other properties ...
    // Fix the missing '{' in the annotation
    @Value("${spring.jpa.hibernate.ddl-auto}")
    private String update;
}

Step 2: Rewrite HibernateUtil for Spring Compatibility

Remove static modifiers and use Spring's lifecycle hooks to initialize the SessionFactory properly:

package com.product.DAO;
import java.util.Properties;
import com.product.Entity.Product;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.service.ServiceRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;

@Component
public class HibernateUtil {
    // Remove static modifier to allow Spring injection
    @Autowired
    private HibernateUtilModel hibernateUtilModel;
    private SessionFactory sessionFactory;

    // Initialize SessionFactory once the bean is created
    @PostConstruct
    public void initSessionFactory() {
        if (sessionFactory == null) {
            try {
                Configuration configuration = new Configuration();
                Properties settings = new Properties();
                settings.put(Environment.DRIVER, hibernateUtilModel.getDriver());
                settings.put(Environment.URL, hibernateUtilModel.getUrl());
                settings.put(Environment.USER, hibernateUtilModel.getUser());
                settings.put(Environment.PASS, hibernateUtilModel.getPass());
                settings.put(Environment.DIALECT, hibernateUtilModel.getDialect());
                settings.put(Environment.SHOW_SQL, hibernateUtilModel.getShow_sql());
                settings.put(Environment.IMPLICIT_NAMING_STRATEGY,hibernateUtilModel.getIMPLICIT());
                settings.put(Environment.PHYSICAL_NAMING_STRATEGY,hibernateUtilModel.getPHYSICAL());
                settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
                settings.put(Environment.HBM2DDL_AUTO, hibernateUtilModel.getUpdate());
                configuration.setProperties(settings);
                configuration.addAnnotatedClass(Product.class);
                ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                        .applySettings(configuration.getProperties()).build();
                sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // Make this a non-static method
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

Step 3: Inject HibernateUtil into Your DAO

Instead of calling static methods, inject the Spring-managed HibernateUtil bean into your DAO:

@Repository // Use @Repository for DAOs to enable Spring's exception translation
public class ProductDAOImpl implements ProductDAO {

    @Autowired
    private HibernateUtil hibernateUtil;

    // ... rest of your DAO methods ...
}

2. Fix the HQL Save Logic

Root Cause

Your current save method uses an INSERT...SELECT HQL query, which copies existing Product records instead of saving the new product parameter. This is not the intended behavior for a save operation, and the redundant call to saveStudent adds unnecessary complexity.

Fix: Simplify the Save Method

Replace the broken logic with a clean implementation that uses Hibernate's core session methods:

@Override
public Product save(Product product) {
    Transaction transaction = null;
    try (Session session = hibernateUtil.getSessionFactory().openSession()) {
        transaction = session.beginTransaction();
        // Save the new product and get its generated primary key
        Serializable savedId = session.save(product);
        // Optional: Fetch the persisted entity (save already updates the product's ID)
        Product savedProduct = session.get(Product.class, savedId);
        transaction.commit();
        return savedProduct != null ? savedProduct : product;
    } catch (Exception e) {
        if (transaction != null) {
            transaction.rollback();
        }
        e.printStackTrace();
        // Throw a custom exception instead of returning a potentially invalid product
        throw new RuntimeException("Failed to save product", e);
    }
}

Why This Works

  • session.save(product) persists the new entity and updates the product object's purchase_item (primary key) with the generated value.
  • The try-with-resources block automatically closes the session, so no manual session.close() is needed.
  • Transactions are handled properly, rolling back on failure and committing on success.

3. Bonus: Use Spring Boot's Built-in Hibernate Support

In Spring Boot, you don’t need a custom HibernateUtil at all! Spring auto-configures a SessionFactory via EntityManagerFactory. Simplify your DAO by injecting EntityManager directly:

@Repository
public class ProductDAOImpl implements ProductDAO {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Product save(Product product) {
        Session session = entityManager.unwrap(Session.class);
        Transaction transaction = session.beginTransaction();
        try {
            session.save(product);
            transaction.commit();
            return product;
        } catch (Exception e) {
            transaction.rollback();
            throw new RuntimeException("Failed to save product", e);
        }
    }
}

This eliminates the need for HibernateUtil and HibernateUtilModel entirely, as Spring Boot handles all Hibernate configuration from your application.yaml.


内容的提问来源于stack exchange,提问作者SpicySandwich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:48:11