Я делаю школьный проект, и он требует от нас создания своего рода веб-приложения для базы данных Oracle. Моя команда выбрала Spring Boot Java с Maven в стиле MVC, и я отвечаю за бэкэнд. Я начал искать это и обнаружил 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);
}
}
Оба метода довольно просты, при необходимости позже будут реализованы дополнительные методы. Вот мое приложение.свойства. Сервер 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. Возможно, это или что-то еще, что я совершенно упустил.
Свойство на стороне Spring — это не «диалект», а «платформа базы данных»:
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
Может зависеть от вашей версии Hibernate, но в любом случае доступные диалекты находятся в этом пакете «org.hibernate.dialect», поэтому проверьте тот, который доступен для Oracle в используемой вами версии.
Я добавил строку, но получил вот такую ошибку
Unable to resolve name [org.hibernate.dialect.Oracle12cDialect] as strategy [org.hibernate.dialect.Dialect]