我正在做一个学校项目,它要求我们为 Oracle 数据库制作某种 Web 应用程序。我的团队选择了 MVC 风格的 Spring Boot Java 和 Maven,我负责后端。我开始查找这个并发现了 JPA。这是我编写的模型的示例。有任何错误请随时指出,我是来学习正确编码的。
package hu.projekt.webshop.Model;
import jakarta.persistence.*;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.relational.core.mapping.Column;
import java.util.List;
@Entity
@Table(name = "CEG")
public class Ceg {
@Id
@Column("NEV")
private String nev;
@Column("ORSZAG")
private String orszag;
@Column("ALAPITVA")
private Integer alapitva;
@OneToMany(mappedBy = "gyarto")
private List<Termek> termekek;
public Ceg() {
}
public Ceg(String nev, String orszag, Integer alapitva) {
this.nev = nev;
this.orszag = orszag;
this.alapitva = alapitva;
}
public String getNev() {
return nev;
}
public void setNev(String nev) {
this.nev = nev;
}
public String getOrszag() {
return orszag;
}
public void setOrszag(String orszag) {
this.orszag = orszag;
}
public Integer getAlapitva() {
return alapitva;
}
public void setAlapitva(Integer alapitva) {
this.alapitva = alapitva;
}
public List<Termek> getTermekek() {
return termekek;
}
public void setTermekek(List<Termek> termekek) {
this.termekek = termekek;
}
}
这是它的基本存储库。
package hu.projekt.webshop.Repository;
import hu.projekt.webshop.Model.Ceg;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CegRepository extends JpaRepository<Ceg, String> {
@Override
<S extends Ceg> S save(S entity);
@Query("SELECT c FROM Ceg c WHERE c.nev = ?1")
Ceg findByNev(String nev);
@Override
List<Ceg> findAll();
@Query("DELETE FROM Ceg c WHERE c.nev = ?1")
boolean deleteByNev(String nev);
}
以及基本服务。
package hu.projekt.webshop.Service;
import hu.projekt.webshop.Model.Ceg;
import hu.projekt.webshop.Repository.CegRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CegService {
private final CegRepository cegRepository;
@Autowired
public CegService(CegRepository cegRepository) {
this.cegRepository = cegRepository;
}
public boolean cegMentes(String nev, String orszag, Integer alapitva) {
return cegRepository.save(new Ceg(nev, orszag, alapitva)) != null;
}
public Ceg cegKereses(String nev) {
return cegRepository.findByNev(nev);
}
public List<Ceg> cegLista() {
return cegRepository.findAll();
}
public boolean cegTorles(String nev) {
return cegRepository.deleteByNev(nev);
}
}
两者都非常基础,如果需要,稍后将实现更多方法。 这是我的 application.properties。 Oracle 服务器在学校,所以我必须使用 PuTTY 进行 SSH 隧道和端口转发。
spring.application.name=Webshop
# Database connection properties
spring.datasource.url=jdbc:oracle:thin:@localhost:15210:orania2
spring.datasource.username=my_username
spring.datasource.password=my_password
oracle.ucp.minPoolSize=5
oracle.ucp.maxPoolSize=20
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
# Hibernate properties
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.main.allow-bean-definition-overriding=true
我编写了一个自定义 DataSource 类,但不确定我是否真的需要。
package hu.projekt.webshop.Utilities;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
public class DataSourceConfig {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${oracle.ucp.minPoolSize}")
private String minPoolSize;
@Value("${oracle.ucp.maxPoolSize}")
private String maxPoolSize;
@Value("${spring.datasource.driver-class-name:oracle.jdbc.pool.OracleDataSource}")
private String driverClassName;
@Bean(name = "OracleUniversalConnectionPool")
@Primary
public DataSource getDataSource() {
PoolDataSource pds = null;
try {
pds = PoolDataSourceFactory.getPoolDataSource();
pds.setConnectionFactoryClassName(driverClassName);
pds.setURL(url);
pds.setUser(username);
pds.setPassword(password);
pds.setMinPoolSize(Integer.parseInt(minPoolSize));
pds.setInitialPoolSize(10);
pds.setMaxPoolSize(Integer.parseInt(maxPoolSize));
} catch (SQLException ea) {
System.err.println("Error connecting to the database: " + ea.getMessage());
}
return pds;
}
}
我当前的问题是Spring应用程序一启动就失败。
Cannot invoke "org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(java.sql.SQLException, String)" because the return value of "org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.sqlExceptionHelper()" is null
我查找过这样的错误,发现 Spring 没有内置的 Oracle Dialect。可能是那个或其他我完全错过的东西。
Spring 端的属性不是“dialect”而是“database-platform”:
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect