所以我必須用 Java 做一個小應用程式 - 我沒有它的背景,所以我真的不知道很多事情(語法上)。我正在使用互聯網和 Intellij 來生成一些代碼。(比如模型)
該程式成功構建,但隨后出現以下運行時錯誤:
Error at initialing DatabaseManager: Exception [EclipseLink-7107] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Error encountered during string decryption.
Internal Exception: java.io.StreamCorruptedException: invalid stream header: BEAD66C6
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.getTransaction()" because "this.entityManager" is null
at database.DatabaseConnection.executeTransaction(DatabaseConnection.java:23)
at database.daos.EchipaDao.create(EchipaDao.java:23)
at Main.main(Main.java:11)
這是我的代碼:
資料庫連接.Java
package database;
import java.util.function.Consumer;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class DatabaseConnection {
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
public DatabaseConnection() {
this.initTransaction();
}
public EntityManager getEntityManager() {
return entityManager;
}
public boolean executeTransaction(Consumer<EntityManager> action) {
EntityTransaction entityTransaction = entityManager.getTransaction();
try {
entityTransaction.begin();
action.accept(entityManager);
entityTransaction.commit();
} catch (RuntimeException e) {
System.err.println("Transaction error: " e.getLocalizedMessage());
entityTransaction.rollback();
return false;
}
return true;
}
private boolean initTransaction() {
try {
entityManagerFactory = Persistence.createEntityManagerFactory("ProiectMipPersistence");
entityManager = entityManagerFactory.createEntityManager();
} catch (Exception e) {
System.err.println("Error at initialing DatabaseManager: " e.getMessage().toString());
return false;
}
return true;
}
}
IDao.java
package database.daos;
import java.util.List;
public interface IDao<T> {
T get(Long id);
List<T> getAll ();
void create (T t);
}
EchipaDao.java
package database.daos;
import database.DatabaseConnection;
import database.models.EchipaEntity;
import javax.persistence.TypedQuery;
import java.util.List;
public class EchipaDao implements IDao<EchipaEntity>{
DatabaseConnection connection = new DatabaseConnection();
public EchipaEntity get(Long id) {
return connection.getEntityManager().find(EchipaEntity.class, Long.valueOf(id));
}
@Override
public List<EchipaEntity> getAll() {
TypedQuery<EchipaEntity> query = connection.getEntityManager().createQuery("SELECT a FROM EchipaEntity a", EchipaEntity.class);
return query.getResultList();
}
public void create(EchipaEntity echipa) {
connection.executeTransaction(entityManager -> entityManager.persist(echipa));
}
}
EchipaEntity.java
package database.models;
import javax.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "echipa", schema = "public", catalog = "dbfdlur9ijidho")
public class EchipaEntity {
@Basic
@Column(name = "nume_echipa", nullable = false, length = -1)
private String numeEchipa;
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
public String getNumeEchipa() {
return numeEchipa;
}
public void setNumeEchipa(String numeEchipa) {
this.numeEchipa = numeEchipa;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EchipaEntity that = (EchipaEntity) o;
return id == that.id && Objects.equals(numeEchipa, that.numeEchipa);
}
@Override
public int hashCode() {
return Objects.hash(numeEchipa, id);
}
}
主程式
import database.daos.EchipaDao;
import database.models.EchipaEntity;
public class Main {
public static void main(String[] args) {
EchipaDao echipaDao = new EchipaDao();
EchipaEntity echipaEntity = new EchipaEntity();
echipaEntity.setNumeEchipa("test");
echipaDao.create(echipaEntity);
System.out.println("Hello world");
}
}
我嘗試在網上搜索(老實說,只是第一個,因為我覺得如果我擺脫了其他人也會消失) - 我找不到任何對我的案子有意義的東西。
那么,為什么會發生這些錯誤,我該如何修復它們?
//編輯:
添加 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>server</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- ECLIPSELINK -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0.0</version>
</dependency>
<!-- POSTGRES -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
</project>
uj5u.com熱心網友回復:
在堆疊跟蹤的末尾,您可以看到問題的根源:
java.io.StreamCorruptedException: invalid stream header: 2666A3B3
雖然有點神秘,但這通常意味著庫的不兼容。
仔細查看您的依賴項,您使用的是相當新版本的 eclipselink(2020 年的 2.7.7),以及其他依賴項的相當舊版本(2010 年的 javax.persistence 2.0.0 和 2014 年的 postgres 9.3)。
如果您轉到 eclipselink 2.7.7 maven 頁面(https://mvnrepository.com/artifact/org.eclipse.persistence/eclipselink/2.7.7),您可以看到用于編譯它的依賴項是 jakarta.persistence( javax.persistence 的新面額)2.2.3,從 2019 年開始,這會更有意義。
對于 Postgress 驅動程式,您可以在其檔案(https://jdbc.postgresql.org/download.html)中看到:
當前版本 42.3.1
這是驅動程式的當前版本。除非您有特殊要求(運行舊應用程式或 JVM),否則您應該使用該驅動程式。它支持 PostgreSQL 8.2 或更新版本,需要 Java 8 或更新版本。它包含對 SSL 和 javax.sql 包的支持。
因此,要整理您的依賴項,請在 pom.xml 中進行以下更改
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>jakarta.persistence</artifactId>
<version>2.2.3</version>
</dependency>
<!-- POSTGRES -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.1</version>
</dependency>
</dependencies>
此外,您正在定義 maven 編譯器插件以使用 java 版本 16,但在屬性中maven.compiler.xxx指向 java 17。這些完全相同,因此您可以指定屬性或插件配置。如果您不使用額外的插件配置,我將始終選擇這些屬性。并根據您的 jdk 版本將其設為 16 或 17(我會使用 17,因為它是最后一個 LTS jdk 版本)
在此 eclipselink github 專案執行緒 ( https://github.com/eclipse-ee4j/eclipselink/issues/269 ) 之后,據說 3.0.0 中添加了 jdk 11 支持。
本地測驗后更新
這意味著,從理論上講,使用 2.7.7 您必須使用 jdk 8。但我剛剛使用 jdk 11 正確運行了您的代碼示例。(16 和 17 使用Unsupported class file major version 60和61.
即使僅在您的原始問題中將 JDK 更改為 11 也是不夠的,您會org.postgresql.util.PSQLException: The authentication type 10 is not supported因為答案開頭提到的庫之間的不兼容問題而得到解決。
更新更新后的依賴
行。這很奇怪,但我認為我們已經解決了最后一個問題。除了所有庫兼容性之外,JDK 版本支持,這是真實的,如果我們深入分析,StreamCorruptedException我們可以看到發生這種情況的確切點:
ValidationException.errorDecryptingPassword(ValidationException.java:901)
谷歌搜索我發現了一個與此相關的奇怪問題,為此我仍在調查根本原因。但它發生的原因是因為您使用的是 32 個字符長的密碼(確切長度)。顯然與 UUID 長度(32 個字符)以及 JPA Provider 如何讀取它有關。當我找到更多答案時,我會更新答案,但更改密碼長度,您應該擺脫StreamCorruptedException(我在本地環境中復制了它)
更新進一步調查
該錯誤已在此處報告https://bugs.eclipse.org/bugs/show_bug.cgi?id=569945
要以這種方式失敗,密碼必須是 32 個字符長(或 32 的倍數)并且由十六進制字符組成。這樣eclipselink認為它是加密的密碼并嘗試解密它,拋出您收到的例外。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/395409.html
上一篇:帶你從零玩轉云服務器
