Java 使用Jpa的spring boot中的动态表名
我的要求:Java 使用Jpa的spring boot中的动态表名,java,spring,spring-boot,jpa,Java,Spring,Spring Boot,Jpa,我的要求: sample.datasource.url=jdbc:postgresql://localhost:5432/postgres sample.datasource.username=postgres sample.datasource.password=postgres sample.datasource.driver-class-name=org.postgresql.Driver sample.jpa.properties.hibernate.jdbc.lob.non_conte
sample.datasource.url=jdbc:postgresql://localhost:5432/postgres
sample.datasource.username=postgres
sample.datasource.password=postgres
sample.datasource.driver-class-name=org.postgresql.Driver
sample.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
sample.jpa.properties.hibernate.default_schema=upload
sample.jpa.hibernate.ddl-auto=create-drop
sample.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
sample.jpa.propertie.hibernate.physical_naming_strategy=com.example.demo.configuration.TableNameStrategy
tableName=dynamictable //table name
我的要求是从属性文件中读取表名
在没有自定义数据库配置的情况下,它可以正常工作
当我宣布以下方式时,其工作正常
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.default_schema=upload
#spring.jpa.hibernate.ddl-auto=create-drop
#sample.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.propertie.hibernate.physical_naming_strategy=com.example.demo.entities.TableNameStrategy.
但是,当我进行自定义数据库配置时,会出现以下错误
Caused by: java.lang.NullPointerException: null
at com.example.demo.entities.TableNameStrategy.toPhysicalTableName(TableNameStrategy.java:25) ~[classes/:na]
at org.hibernate.boot.model.relational.Namespace.createTable(Namespace.java:92) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.addTable(InFlightMetadataCollectorImpl.java:772) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.cfg.annotations.TableBinder.buildAndFillTable(TableBinder.java:509) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.cfg.annotations.EntityBinder.bindTable(EntityBinder.java:848) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:647) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:250) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:231) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:274) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 17 common frames omitted
这是我的自定义数据库配置代码:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef="sampleEntityManager",
transactionManagerRef="sampleTransactionManager",
basePackages= {"com.example.demo.repo"})
public class SampleConfiguration {
@Autowired
Environment env;
@Bean(name="sampleDataSource")
@Primary
public DataSource dmsDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("sample.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("sample.datasource.url"));
dataSource.setUsername(env.getProperty("sample.datasource.username"));
dataSource.setPassword(env.getProperty("sample.datasource.password"));
return dataSource;
}
@Primary
@Bean(name = "sampleEntityManager")
public LocalContainerEntityManagerFactoryBean dmsEntityManagerFactory(EntityManagerFactoryBuilder builder) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.jdbc.lob.non_contextual_creation",env.getProperty("sample.jpa.properties.hibernate.jdbc.lob.non_contextual_creation"));
properties.put("hibernate.default_schema", env.getProperty("sample.jpa.properties.hibernate.default_schema"));
properties.put("hibernate.ddl-auto", env.getProperty("sample.jpa.properties.hibernate.ddl-auto"));
properties.put("hibernate.physical_naming_strategy",env.getProperty("sample.jpa.properties.hibernate.physical_naming_strategy"));
return builder
.dataSource(dmsDataSource())
.properties(properties)
.packages("com.example.demo.entities")
.persistenceUnit("dms")
.build();
}
@Primary
@Bean(name = "sampleTransactionManager")
public PlatformTransactionManager dmsTransactionManager(@Qualifier("sampleEntityManager") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
我的属性文件:
sample.datasource.url=jdbc:postgresql://localhost:5432/postgres
sample.datasource.username=postgres
sample.datasource.password=postgres
sample.datasource.driver-class-name=org.postgresql.Driver
sample.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
sample.jpa.properties.hibernate.default_schema=upload
sample.jpa.hibernate.ddl-auto=create-drop
sample.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
sample.jpa.propertie.hibernate.physical_naming_strategy=com.example.demo.configuration.TableNameStrategy
tableName=dynamictable //table name
我的实体类
@Entity
@Data
public class Sample {
@Id
private Integer id;
}
使用自定义数据库配置时,它无法按预期工作。有人能告诉我哪里出错吗?应用程序中指定的属性。属性不正确 您指定的内容:
spring.jpa.propertie.hibernate.physical\u naming\u strategy=com.example.demo.entities.TableNameStrategy
正确:
spring.jpa.hibernate.naming.physical strategy=com.example.demo.entities.TableNameStrategy
我建议您检查参数是否是必需的,因为它可能导致NullPointerException
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return new Identifier(toIdentifier(getTableName()).getText(), name.isQuoted());
}
private String getTableName() {
return environment.getRequiredProperty(PROPERTY_TABLE_NAME);
}
因为Identifier.toIdentifier可以返回空值
public static Identifier toIdentifier(String text) {
if ( StringHelper.isEmpty( text ) ) {
return null;
}
...
}
尝试将环境变量设置为“private final”,并将其设置在构造函数中,它表示行号25
(TableNameStrategy.java:25)
@r33tnup正如您所说的private final String table,我尝试了以下方法;TableNameStrategy(){table=env.getProperty(“tableName”);}但它不起作用您的属性中缺少一个“s”:property
public final class StringHelper {
...
public static boolean isEmpty(String string) {
return string == null || string.isEmpty();
}
...