在默认安装的时候 IntelliJ IDEA 是不显示工具栏的。 我们可以在安装完成后显示工具栏。 如果上面图所示。 解决办法 可以单击在 View 视图中,选择显示,然后选择显示工具栏即可。 通过上面的选项就可以完成显示了。 https://www.ossez.com/t/intellij-idea/13867
在默认安装的时候 IntelliJ IDEA 是不显示工具栏的。 我们可以在安装完成后显示工具栏。 如果上面图所示。 解决办法 可以单击在 View 视图中,选择显示,然后选择显示工具栏即可。 通过上面的选项就可以完成显示了。 https://www.ossez.com/t/intellij-idea/13867
假设我们有一个 proto 文件命名为:simple.proto simple.proto 的代码在 https://github.com/cwiki-us-demo/protocol-buffers-demo-java/blob/master/src/main/proto/simple.proto 页面中可以访问到。 你可以 Clone 项目到本地后进行执行。 你可以通过运行下面的命令来将 simple.proto 文件为基础生成一个 Java 对象 protoc --proto_path=src --java_out=src/main/java src/main/proto/simple.proto 生成结果如果正常的话,应该是没有输出的。 然后你访问特定的文件夹后就可以看到生成的 Java 对象。 生成的文件的路径和文件在 com.insight.demo.protocolbuffers.mode 这个包中。 请注意,你不能对手动对这个文件进行编译,这个文件都应该是通过程序自动生成的。 https://www.ossez.com/t/protocol-buffers-java/13865
本文主要介绍 protobuf 编译器在 Windows 下的安装 下载编译器 访问 Releases · protocolbuffers/protobuf · GitHub 链接然后针对不同的操作系统下载最新的编译器版本。 下载完成后到本地计算机上找到这个文件并且解压。 解压文件 然后将下载的压缩文件解压到 D:\Dkits\protobuf 文件夹中。 当然你也可以解压到不同的文件夹中。 解压后的文件夹目录如下。 设置 PATH 当完成下面解压后,你可以将文件所在的 bin 目录中设置到 PATH 里面。 上面就是设置好的 PATH 目录。 然后保存退出。 校验安装 在命令行工具中,运行命令: protoc --version 如果能够看到版本输出的话,就说明你的 protoc 已经被正确的配置到操作系统中了。 如上图,我们能看到正确的版本输出。 https://www.ossez.com/t/protobuf-windows/13864
完整的异常信息如下: 12:00:50.310 [http-nio-8080-exec-5] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception com.fasterxml.jackson.core.JsonParseException: Unexpected character (' ' (code 160)): was expecting double-quote to start field name at [Source: (String)"{ "action": "dom", "dom": "P1D", "pageSize": 100, "page": 0 }"; line: 2, column: 2] 上面的错误提示为输入的 JSON 数据不正确,没有办法处理。 问题和解决 这个问题困惑了我们很久。 原因后来发现在输入的 JSON 格式,不知道什么原因使用了双引号。 我们使用的是 POSTMAN 发送的数据。 后来,我们修改了数据使用的格式为 JSON 格式。 然后再将数据发送到后台就没有这个问题了。 这个问题的原因我们认为是 HTTP 请求的格式定义导致了后台的 Spring 处理逻辑没有办法处理输入的字符串,在进行 JSON 格式数据转换的时候出错了。 https://www.ossez.com/t/java-post-json-code-160-was-expecting-double-quote-to-start-field-name/13863
通常我们在 OOP 设计中都会使用到继承。 但是在继承对象之间的强制转换可能会遇到 java.lang.ClassCastException 异常的错误。 错误的日志如下: 19:58:25.010 [http-nio-8080-exec-5] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: class com.ossez.usreio.mls.common.models.response.ListingResponse cannot be cast to class com.ossez.usreio.mls.common.models.response.ListingDetailResponse (com.ossez.usreio.mls.common.models.response.ListingResponse and com.ossez.usreio.mls.common.models.response.ListingDetailResponse are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @4ee285c6)] with root cause java.lang.ClassCastException: class com.ossez.usreio.mls.common.models.response.ListingResponse cannot be cast to class com.ossez.usreio.mls.common.models.response.ListingDetailResponse (com.ossez.usreio.mls.common.models.response.ListingResponse and com.ossez.usreio.mls.common.models.response.ListingDetailResponse are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @4ee285c6) 问题和原因 这个问题出现的原因就是继承类之间强制转换的错误。 同时这个错误是运行时错误,不是编译错误,因此你编译的时候是没有这个错误的。 考察下面的代码: Parent b = new parent(); Child c = (Child) b ; 采用该方法不能实现对象类型由超类向子类的转换。 上面的原因是父类的对象是由父类创建的,然后你尝试将父类创建的对象强制转换到子类中。 因为父类创建的对象和子类需要创建的对象分别使用不同的地址空间,那在转换的时候将会出现地址空间引用的错误,因此 JVM 会认为你将 2 个完全不同类型的对象进行转换,这个时候出现上面的运行时错误。 要解决这个问题的办法就是在创建父类的时候使用子类来创建,并且强制将创建的父类转换为子类就可以了。 使用这种创建方法就能保证使用相同的地址空间。 将上面的语句改成: Parent b = new Child (); Child c = (Child) b ; 就可以了。 https://www.ossez.com/t/java-java-lang-classcastexception/13862
在 Hibernate 实体对象定义 Enum 类型。 可以使用下面的代码 @Column(name = "LISTING_TYPE") @Enumerated(EnumType.ORDINAL) private ListingType listingType; 上面代码中有一个关键的注解 就是 Enumerated。 在这里你可以为你的字段定义 EnumType。 这里其实 有 2 种类型,第一种类型为 ORDINAL,第二种类型为 STRING。 这 2 种类型是分别对应的是整数类型和字符串类型。 同时这 2 种类型是在 包 javax.persistence 中定义的。 对应数据库 对应的数据库,如果你使用的类型为 EnumType.ORDINAL 的话,你对应的数据库字段可以使用为 int。 否则你需要在你的数据库中使用字段为 VARCHAR 或者任何其他类型的字段。 通常我们认为使用整数在数据库中的效率可能更高。 因此在实际定义的时候,使用 EnumType.ORDINAL 的机会更多。 https://www.ossez.com/t/hibernate-enumerated/13853
这个警告通常在你升级 Hibernate 后会出现,主要是提示你应该使用 JPA 来进行查询。 警告信息如下: HHH90000022: Hibernate's legacy org.hibernate.Criteria API is deprecated; use the JPA javax.persistence.criteria.CriteriaQuery instead 老的查询方式 考察下面的代码: Factory.getSession().createCriteria(classArg); 上面的代码是获得一个 Session 后创建 createCriteria 来进行查询。 如果你查看 createCriteria 这个方法的源代码的话。 上面提示这个查询方法将会逐步被丢弃。 因此不建议你继续使用。 考察下面的代码,我们是来从一个实体对象中进行查询。 Criteria cr = Factory.createCriteria(MlsListing.class); cr.add(Restrictions.ge("dateM", new DateTime().minusDays(100).toDate())); cr.addOrder(Order.desc("dateM")); 上面的代码是首先通过实体创建一个 Criteria,然后再设置查询条件。 如果使用 JPA 的话就不能这样写了。 JPA 写法 与上面对应的是 JPA 的写法。 完整的代码如下: CriteriaBuilder builder = Factory.getSession().getCriteriaBuilder(); CriteriaQuery<MlsListing> criteriaQuery = builder.createQuery(MlsListing.class); Root<MlsListing> root = criteriaQuery.from(MlsListing.class); criteriaQuery.select(root); criteriaQuery.where(builder.greaterThan(root.get("dateM"), new DateTime().minusDays(100).toDate())); // criteriaQuery.where(builder.greaterThan(root.get(MlsListing_.DATE_M), new DateTime().minusDays(100).toDate())); Query query = Factory.getSession().createQuery(criteriaQuery); query.setMaxResults(1000); mlsListingList = query.getResultList(); 代码解读 需要从 Session 中获得 CriteriaBuilder 实例 从 CriteriaBuilder 实例中创建 CriteriaQuery 从 CriteriaQuery 中创建 Root 实例 将 root 实例返回设置到 CriteriaQuery 中 在 CriteriaQuery 中创建 Where,Order 等条件 从 Session中获得 Query 实例,在创建这个 Query 实例的时候需要 CriteriaQuery 才可以创建。 为 Query 设置返回参数集 执行查询 如果单纯的从步骤的角度来说,上面的过程更加复杂了。 原因有,从 Session 中需要获得 CriteriaBuilder 和 Query 2 个实例。 CriteriaQuery 的创建需要实体。 CriteriaQuery 需要解决 2 个问题,从哪里去查询,实际上是从 Root 去查询,这个是 select 这个语句表达的。 查询条件是什么,这个是 where 语句表达的。 因为是 从 Root 里面查,所以需要设置 Root 对象,root 对象又是从 criteriaQuery 中的 from 来的。 正是因为上面的问题,才导致这个 JPA 查询有点绕。 总结 对 JPA 的查询我们进行一个小总结。 查询的基础是从 session 中运行 Query 语句。 第一步,从 Session 中创建 CriteriaBuilder ,这个不需要实体类。 第二步,从 CriteriaBuilder 的实例中创建 CriteriaQuery,这个需要实体类,同时解决从哪里查(Root)和 怎么查的问题(Select 和 Where) 第三步,执行查询,这个步骤需要从 Session 中创建 Query ,并且执行 CriteriaQuery 的实例。 通过上面 3 个步骤是不是更加容易帮助你理解了呢? https://www.ossez.com/t/hibernate-hhh90000022/13852
Hibernate 在 5 以后的版本中全面推进使用 JPA 的查询语法,甚至准备废弃掉自己已有的查询语法。 什么是 JPA JPA 全称为 Java Persistence API ,Java 持久化API是Sun公司在java EE 5规范中提出的 Java 持久化接口。 JPA吸取了目前Java持久化技术的优点,旨在规范、简化Java对象的持久化工作。 使用JPA持久化对象,并不是依赖于某一个ORM框架。 换句话说就是 JPA 是一个技术规范,你可以使用各种框架来进行实现。 比如你可能听到最多的 Hibernate, OpenJPA,或者 EclipseLink 等都是 JPA 的实现。 Hibernate 和 JPA 的关系 根据数据访问的层次来说,我们如果使用 Hibernate 的话,通常我们需要写的代码都在数据访问层。 然后在数据访问层中编写查询代码。 这个查询代码可以使用 Hibernate Native API ,也可以使用 JPA。 在 Hibernate 5 及其后续版本中,你可能会看到下面的这个警告: HHH90000022: Hibernate's legacy org.hibernate.Criteria API is deprecated; use the JPA javax.persistence.criteria.CriteriaQuery instead 上面警告的意思是 Hibernate 准备丢弃掉自己的 Hibernate Native API 查询 API 了。 在你的数据访问层的代码中,你需要采取 JPA 的写法了。 如果你对老的 Hibernate 版本进行升级的时候,你可能会遇到上面的问题,你需要重新调整不少的写法。 可以说 Hibernate 正在全面向 JPA 的写法靠拢。 https://www.ossez.com/t/hibernate-jpa/13851
如果不在 IntelliJ IDEA 中配置的话,将会出现编译错误。 这是因为 Metamodel 源代码不是在 src 目录中的,而是在编译的时候生成的。 要解决这个问题其实也非常简单,按照下面 2 个步骤就可以了。 配置 首先需要进入进入 IntelliJ IDEA 的编译配置。 然后选择编译,然后选择声明处理器,然后 Check 上启用声明处理器。 在完成上面的配置后单击 OK 保存退出。 添加源代码 在生成的 Metamodel 代码中,单击右键。 然后单击鼠标右键,选择生成 Metamodel 的目录为 生成的源代码 Root。 如上面图片中显示的内容。 然后单击确定后就可以让你的源代码编译的时候没有错误了。 再次确认 然后选择文件,然后选择项目结构。 然后选择模块。 在模块中,需要确定生成的文件夹在源代码目录中。 只有完成上面的设置才会让 IntelliJ IDEA 能够识别生成的文件。 并且在 IntelliJ IDEA 没有编译错误。 https://www.ossez.com/t/intellij-idea-metamodel/13850
要在 Hibernate 中生成 JPA 的 Metamodel。 你只需要在 pom.xml 进行下面的 2 个操作就可以了。 添加依赖 在 POM 中添加下面的依赖。 <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-jpamodelgen</artifactId> <version>5.6.3.Final</version> </dependency> 编译插件 在编译插件中,添加编译参数 <compilerArguments> <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor> </compilerArguments> 完整的编译参数如下图 注意上图中的插件配置。 进行编译 运行命令:mvn compile 输出如下: PS C:\WorkDir\USRealEstate\Source-Code\mls-common> mvn compile [INFO] Scanning for projects... [INFO] [INFO] --------------------< com.ossez.usreio:mls-common >--------------------- [INFO] Building Mls-Common 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mls-common --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 5 resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ mls-common --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 35 source files to C:\WorkDir\USRealEstate\Source-Code\mls-common\target\classes [INFO] /C:/WorkDir/USRealEstate/Source-Code/mls-common/src/main/java/com/ossez/usreio/mls/common/dao/factories/ListingMlsPhotoFactory.java: Some input files use or override a deprecated API. [INFO] /C:/WorkDir/USRealEstate/Source-Code/mls-common/src/main/java/com/ossez/usreio/mls/common/dao/factories/ListingMlsPhotoFactory.java: Recompile with -Xlint:deprecation for details. [INFO] /C:/WorkDir/USRealEstate/Source-Code/mls-common/src/main/java/com/ossez/usreio/mls/common/dao/factories/ListingMlsPhotoFactory.java: Some input files use unchecked or unsafe operations. [INFO] /C:/WorkDir/USRealEstate/Source-Code/mls-common/src/main/java/com/ossez/usreio/mls/common/dao/factories/ListingMlsPhotoFactory.java: Recompile with -Xlint:unchecked for details. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.738 s [INFO] Finished at: 2022-01-12T16:52:51-05:00 [INFO] ------------------------------------------------------------------------ PS C:\WorkDir\USRealEstate\Source-Code\mls-common> 然后 Maven 将会在 target 文件夹中生成 Metamodel 的源代码。 生成的源代码如上图。 https://www.ossez.com/t/hibernate-jpa-metamodel/13849