[英]Unable to connect IBMi machine with Spring Data & JPA
嘗試使用 Spring 數據和 JPA 連接 IBMi 機器,但它生成錯誤:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [HibernateJpaConfiguration.class]: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.AbstractMethodError: Receiver class com.ibm.as400.access.AS400JDBCConnectionImpl does not define or inherit an implementation of the resolved method 'abstract boolean isValid(int)' of interface java.sql.Connection.
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.8.jar:5.3.8]
at spring.security.as400.SpringSecurityDemoApplication2.main(SpringSecurityDemoApplication2.java:10) ~[classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.AbstractMethodError: Receiver class com.ibm.as400.access.AS400JDBCConnectionImpl does not define or inherit an implementation of the resolved method 'abstract boolean isValid(int)' of interface java.sql.Connection.
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.8.jar:5.3.8]
Caused by: java.lang.AbstractMethodError: Receiver class com.ibm.as400.access.AS400JDBCConnectionImpl does not define or inherit an implementation of the resolved method 'abstract boolean isValid(int)' of interface java.sql.Connection.
at com.zaxxer.hikari.pool.PoolBase.checkValidationSupport(PoolBase.java:458) ~[HikariCP-3.4.5.jar:na]
該項目是學習 Spring 數據使用 JPA 連接 IBMi 機器的入門項目,但似乎 Spring 數據沒有為此提供最簡單的方法。
我的項目類是:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>Spring-Security-JT400</groupId>
<artifactId>Security-JT400</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Security-JT400</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.sf.jt400</groupId>
<artifactId>jt400</artifactId>
<version>10.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter
{
@Autowired
CustomUserDetailsService customUserDetailsService;
@Bean
AuthenticationProvider authenticationProvider()
{
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(customUserDetailsService);
provider.setPasswordEncoder(new BCryptPasswordEncoder());
return provider;
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/home").hasAuthority("USER")
.antMatchers("/admin").hasAuthority("ADMIN")
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
@Service
public class CustomUserDetailsService implements UserDetailsService
{
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
User user = userRepository.findByUsername(username);
if (user == null)
{
throw new UsernameNotFoundException("User not found.");
}
return new CustomUserDetails(user);
}
}
@Repository
public interface UserRepository extends JpaRepository<User, Integer>
{
public User findByUsername(String username);
}
@RestController
public class HomeController
{
@GetMapping("/home")
public String home()
{
return "This is Home Page.";
}
@GetMapping("/admin")
public String admin()
{
return "This is Admin Page.";
}
}
public class CustomUserDetails implements UserDetails
{
private User user;
public CustomUserDetails(User user)
{
super();
this.user = user;
}
private static final long serialVersionUID = -228521734196009612L;
@Override
public Collection<? extends GrantedAuthority> getAuthorities()
{
return Collections.singleton(new SimpleGrantedAuthority(user.getRole()));
}
@Override
public String getPassword()
{
return user.getPassword();
}
@Override
public String getUsername()
{
return user.getUsername();
}
@Override
public boolean isAccountNonExpired()
{
return true;
}
@Override
public boolean isAccountNonLocked()
{
return true;
}
@Override
public boolean isCredentialsNonExpired()
{
return true;
}
@Override
public boolean isEnabled()
{
return true;
}
}
@Entity
public class User
{
@Id
private int id;
private String username;
private String password;
private String role;
}
@SpringBootApplication
public class SpringSecurityDemoApplication2 {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityDemoApplication2.class, args);
}
}
spring.datasource.url=jdbc:as400://192.168.xx.xxx/;translate binary=true;prompt=false
spring.datasource.username=USERNAME
spring.datasource.password=PASSWORD
spring.datasource.driver-class-name=com.ibm.as400.access.AS400JDBCDriver
spring.jpa.database-platform=org.hibernate.dialect.DB2400Dialect
注意:使用相同的類並在application.properties中進行更改,能夠連接到 MYSQL 數據庫。
我遇到過同樣的問題。 問題是方法abstract boolean isValid(int)
似乎沒有實現,或者不能正常工作(我不確定)。 基本上,它是在檢查與數據庫的連接是否健康。 令人高興的是,您可以將其更改為您自己的。 在 spring 引導中,只需添加到application.properties:spring.datasource.hikari.connection-test-query : spring.datasource.hikari.connection-test-query: values 1
對我來說,值 1有效(我使用的是 AS400 DB2),但對於其他數據庫,您可能需要使用不同的數據庫,請查看此答案
我有多個數據源,不幸的是將它們添加到 application.properties 是不夠的,我必須像這樣在 PersistanceConfigurator 中設置它:
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource as400DataSource() {
HikariDataSource dataSource = (HikariDataSource) DataSourceBuilder.create().build();
dataSource.setConnectionTestQuery("values 1");
return dataSource;
}
現在它工作得很好。
嘗試在 @SpringBootApplication 下面添加 @EnableJpaRepositories 注釋
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.