JPA这个烂东西


竟然64个annotation,没有分类,放在同一个package下,同一个package(javax.persistance)还有其他java文件,共有88个java文件。不看内容本身,单从表面,都觉得这是混乱不堪的事情。这是那个猪头的杰作?glassfish上下载的源码中,这些java文件似乎都没有author,估计也不好意思把名字放出来见人吧!

------

觉得对象关系存储方面一直没有突破,也没有好的产品出来,其中一个原因,就是从没有过优秀的工程师投身过这个领域。关系数据库为什么能够一直坚守领地,成为绝大多数商业应用的基石,其中一个原因就是有过大量的精英投身于此,包括两个图灵奖获得者。

关系数据库,为了描述关系,创造一门SQL语言,将关系一些操作,例如投影(select)、选择(where)、分组(group by)等等,抽象得形象易懂,功能强大。对于数据的操作,SQL语言是最强大,也是最方便的,也是最易于使用的。一些非程序员的IT从业人员,非计算机专业的人员都能够熟练掌握SQL。

OO和Relational都是伟大的技术,从计算机最高荣誉奖可以看出这两个技术的伟大。OO的图灵奖获得者是三个,Relational的图灵奖获得者是两个。

面向对象技术自1967年simula引进依赖,所想披靡,93年-98年从C++开始流行,然后到Java,成为主流编程技术。Relational没有OO那么辉煌,但是在数据存储方面的地位固如磐石,长期占据绝对的地位。

曾经OO技术涉足于数据存储领域,但终究没有成功。面向对象数据库的变现总是差强人意,面向对象的方式操作数据,总是不如使用关系那么方便,那么灵活,那么易于使用,那么好的性能。于是人们在数据存储和处理方面,不在青睐面向对象技术,而是仍然使用关系方式,使用SQL语言,使用关系运算操作数据。面向对象数据库成了昙花一现的东西,并且可能永远都不会再流行了。

OO成了主流编程技术,Relational占据了绝对的数据存储地位,这两大技术需要交互,需要桥接,这需要OR-Mapping。Relational虽然好,但我们也要与时俱进,所以也需要OR-Mapping。

但是,做OR-Mapping时,不积极吸取relational方式对数据处理的灵活性、方便性、简单性,而只强调Relational和对象之间的的Mapping,试图以面向对象的方式操作数据,这是错误的方向。以前的EJB、现在Hibernate、JPA都犯了同样的错误,试图以更面向对象的方式操作数据,从而导致复杂混乱的模型,这也是JPA的现状吧。例如user.getGroup(),目前的ORM试图以纯OO的方式操作数据,所引起的LazyLoad、n+1等问题,使得事情变得复杂而且混乱不堪。

一些开发人员,去学习Hibernate,不学习SQL,有人提倡,只需要了解面向对象编程技术,不需要了解关系技术,亦属于本末倒置。需求人员都会用的SQL语言,对数据操作最方便最简单最强大的SQL语言,竟然成了令人生畏的纸老虎,可笑啊。

-------------

以下是过去的一些业界浮躁不理智:

1、面向对象数据库。曾被热衷而吹捧,面向对象数据库的变现总是差强人意,面向对象的方式操作数据,总是不如使用关系那么方便,那么灵活,那么易于使用,那么好的性能。于是人们在数据存储和处 理方面,不在青睐面向对象技术,而是仍然使用关系方式,使用SQL语言,使用关系运算操作数据。面向对象数据库成了昙花一现的东西,并且可能永远都不会再 流行了。

2、JDO投票闹剧。2004-2005年,JDO的JSR在JCP投票被否决的,无聊者在Java社区以及媒体发起闹事,阴谋论其为政治谋杀,几大公司是的迫于形象,重新投票使得JDO被通过,但JDO这种静态AOP叫雕虫小计式技术,不单开发过程不方便,而且会使得"enhance"之后的代码不可调试。这完全是对开发者不友好的技术,没有前途的技术,竟然会有人为它在JCP投票不通过鸣不平。这件事情使得我更坚信一点,不要相信那些技术编辑的判断力。

3、AOP。也是最近这几年流行的一个名词了。起了一个和OOP相似的名字,但是和伟大的OOP相比,它完全不算是什么。AOP只是一种很小很小的技巧而已,静态的AOP是黑客式的插入代码,会导致代码不可调试,动态的AOP能力有限,AOP最常被引用例子“日志AOP”是不合适,有用的日志通常是精心设计的,AOP方式的日志在生产环境中基本上是不可用。OO这么多年,这么为伟大,人们总是希望自己能做点什么和伟大的OO相比,于是命名为AOP,这是一个可笑的名字,前些年还有人谈论面向对象的未来是面向事实,也是同样的可笑。AOP有价值,但它是一种小技巧,和名字不般配。

--------------

目前在流行,但是可能是不理智的技术:

1、hibernate之类的ORM,试图以面向对象方式操作数据,和面向对象数据库一样,重蹈覆辙。
2、Ruby,一个小脚本语言,只是因为动态类型、mixin之类的功能,还没有被证明有生产力,有效益可用的脚本语言,就被媒体吹到天上去。Ruby有价值,但是最终结果会离大家的期待相差甚远。


转载于:https://www.cnblogs.com/jobs/archive/2008/02/02/1062031.html

<think>嗯,用户现在问的是“这两个时JPA的”,看起来可能是打字错误,应该是“这两个是JPA的”。结合之前的对话历史,用户之前询问了关于Spring Boot启动时出现的Spring Data Redis无法识别Repository的问题,现在可能是在确认这两个Repository是否属于JPA。 首先,我需要回顾之前的对话内容。用户之前遇到的日志信息指出,Spring Data无法确定TokenPoolRepository和UsersRepository的存储类型,并建议添加Redis相关的注解或继承KeyValueRepository。这说明这两个Repository可能被错误地配置为使用Redis,而实际上用户可能原本想用JPA。 用户现在问这两个Repository是否是JPA的,可能是想确认问题是否出在Repository的存储技术配置上。我需要解释这两个Repository当前为什么会被识别为可能属于Redis,而不是JPA,以及如何正确地将它们配置为JPA的Repository。 接下来,我需要分析可能的情况。如果用户原本打算使用JPA,但出现了Redis的警告,可能是因为项目中同时引入了Spring Data JPA和Spring Data Redis的依赖,导致Spring Data在自动检测时无法确定正确的存储技术。这时候,需要检查依赖配置,排除不需要的存储技术,或者在Repository上明确指定使用JPA。 此外,用户可能在实体类上使用了JPA的注解(如@Entity),但没有正确配置,或者Repository接口继承了JpaRepository而不是其他存储技术的接口。需要指出正确的JPA配置方式,比如使用@Entity和@Table注解实体类,让Repository继承JpaRepository,并确保启用JPA的仓库扫描。 同时,可能需要提醒用户检查启动类上的注解,确保使用了@EnableJpaRepositories来指定JPA Repository的扫描路径,避免与其他存储技术的Repository冲突。另外,检查application.properties或application.yml中的数据库配置是否正确,确保JPA能够正常连接数据库。 还有可能用户误将JPA的Repository放在了Spring Data Redis的扫描路径下,导致Spring尝试将它们识别为Redis仓库。这时候需要调整包结构,或者通过@EnableJpaRepositories和@EnableRedisRepositories明确指定各自的扫描路径,避免混淆。 最后,总结解决方案,帮助用户确认这两个Repository应为JPA配置,并提供具体的步骤,如添加JPA注解、继承JpaRepository、排除冲突依赖、调整扫描路径等,确保用户能够正确配置以避免之前的警告信息。</think>以下是关于这两个Repository与JPA关系的分析及解决方案: --- ### 一、现象判断 当看到日志中提示的`Could not safely identify store assignment`警告时,**如果这两个Repository本应是JPA的,说明存在存储技术冲突**。以下是核心问题拆解: --- ### 二、根本原因 #### 1. **混合存储技术依赖** - **典型场景**:项目同时引入`spring-boot-starter-data-jpa`和`spring-boot-starter-data-redis` ```xml <!-- 错误示例:同时存在JPA和Redis依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` #### 2. **实体类未正确标记** - **JPA实体需要明确注解**:`@Entity`、`@Table`等 ```java // 错误示例:未标注JPA注解的实体类 public class Users { private Long id; // 缺少@Id标注 // 其他字段... } ``` #### 3. **Repository定义不规范** - **JPA Repository需继承特定接口**:`JpaRepository` ```java // 错误示例:未继承JpaRepository的接口 public interface UsersRepository { // 方法定义... } ``` --- ### 三、解决方案 #### 步骤1:明确标识JPA实体 ```java @Entity // 关键注解 @Table(name = "users") // 定义表名 public class Users { @Id // 必须标注主键 @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 其他字段... } ``` #### 步骤2:正确继承JPA接口 ```java // 继承JpaRepository<实体类, 主键类型> public interface UsersRepository extends JpaRepository<Users, Long> { // 可添加自定义查询方法 Optional<Users> findByUsername(String username); } ``` #### 步骤3:排除Redis干扰 - **方法1:移除Redis依赖**(若不需要Redis) ```xml <!-- 删除或注释掉Redis依赖 --> <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> --> ``` - **方法2:限制扫描范围**(若需同时使用多存储技术) ```java @EnableJpaRepositories(basePackages = "indi.backend.repository.dao") // 明确扫描JPA仓库 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` --- ### 四、验证配置 #### 1. 检查启动日志 - 成功时应出现JPA初始化日志: ``` Hibernate: create table users (id bigint not null, ...) ``` #### 2. 编写测试用例 ```java @SpringBootTest public class JpaTest { @Autowired private UsersRepository usersRepository; @Test void testSave() { Users user = new Users(); user.setUsername("testUser"); usersRepository.save(user); assertNotNull(usersRepository.findByUsername("testUser")); } } ``` --- ### 五、常见错误排查 | 现象 | 解决方案 | |------|----------| | 出现`No qualifying bean of type 'UsersRepository'` | 检查是否忘记添加`@Repository`注解或继承`JpaRepository` | | 实体字段未映射到数据库列 | 确保字段有`@Column`注解或遵循JPA命名策略 | | 日志中仍有Redis警告 | 检查是否在`application.yml`中误配置了`spring.data.redis.repositories.enabled=true` | --- ### 六、架构对比 | 技术 | JPA标识方式 | Redis标识方式 | |------------|------------------------|------------------------| | **实体类** | `@Entity` + `@Table` | `@RedisHash` | | **主键** | `@Id` + `@GeneratedValue` | `@Id` | | **Repository** | 继承`JpaRepository` | 继承`CrudRepository`或直接定义 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值