如何在Spring Java Hibernate实体中实现Grails Domain的类似功能?
关于Grails Domain与Spring+Hibernate实体的相关问题
Grails的Domain类自带save()、get()等方法,请问:
- Grails的Domain是否属于Spring Bean?
- 能否在Spring整合Hibernate的Java实体类中实现类似
user.save()这类调用方式? - 是否有相关实践案例?
示例实体类:
@Entity @Table(name = "t_users") public class User { @Id @GeneratedValue(strategy = GenerationType.UUID) @Column(name = "id") private UUID id; @Column(name = "first_name", nullable = false) public String firstName; }
希望能以user.save()的方式使用该类。
问题解答
1. Grails的Domain是否属于Spring Bean?
Grails的Domain类不是传统意义上的Spring Bean。Grails通过GORM框架给Domain类动态注入了save()、get()等持久化方法,这些Domain实例是由Grails自身的实例化机制创建的,而非Spring容器管理。不过在Grails应用中,Domain类的相关代理或辅助Bean会被Spring管理,但Domain实例本身不属于Spring Bean范畴。
2. 能否在Spring+Hibernate实体中实现类似user.save()的功能?
可以实现,但需要自行扩展,核心思路是给实体类添加持久化方法,内部调用Spring管理的EntityManager或JpaRepository完成数据库操作。
3. 实践案例
方案1:实体类内部注入EntityManager(借助Spring的@Configurable)
这种方式需要启用Spring的AspectJ织入,让Spring能给非容器创建的实体类注入依赖:
- 开启Spring的@Configurable支持,在配置类添加:
@Configuration @EnableSpringConfigured public class AppConfig { }
- 修改User实体类,注入EntityManager并实现save方法:
@Entity @Table(name = "t_users") @Configurable(preConstruction = true) public class User { @Id @GeneratedValue(strategy = GenerationType.UUID) @Column(name = "id") private UUID id; @Column(name = "first_name", nullable = false) public String firstName; @Autowired private transient EntityManager entityManager; public User save() { if (id == null) { entityManager.persist(this); } else { entityManager.merge(this); } return this; } }
注意:entityManager要加transient避免序列化问题,同时需确保项目配置了AspectJ织入(比如添加Maven依赖和插件)。
方案2:通过静态工具类获取Spring容器中的Repository
如果不想用AspectJ,可以借助静态工具类获取Spring上下文,调用Repository的方法:
- 实现Spring上下文持有类:
@Component public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; } public static <T> T getBean(Class<T> clazz) { return context.getBean(clazz); } }
- 创建UserRepository:
public interface UserRepository extends JpaRepository<User, UUID> { }
- 修改User实体类添加save方法:
@Entity @Table(name = "t_users") public class User { @Id @GeneratedValue(strategy = GenerationType.UUID) @Column(name = "id") private UUID id; @Column(name = "first_name", nullable = false) public String firstName; public User save() { UserRepository repository = SpringContextHolder.getBean(UserRepository.class); return repository.save(this); } }
这种方式不需要AspectJ,但静态工具类的使用会增加代码耦合度,需要权衡。
内容的提问来源于stack exchange,提问作者William Arustamyan
相关产品推荐
相关产品推荐

