首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring boot2 SQLite的JPA命名策略

Spring boot2 SQLite的JPA命名策略
EN

Stack Overflow用户
提问于 2019-10-04 14:46:19
回答 1查看 396关注 0票数 0

我想用CrudRepository实现spring 2应用程序。我不知道我的应用程序中的命名策略是怎么回事。当我在存储库中调用一个方法(例如findAll())时,它会转换数据库中表的名称,并导致查询崩溃。当然,我尝试过类似问题的解决方案:ImprovedNamingStrategy no longer working in Hibernate 5 Hibernate naming strategy changing table names

代码语言:javascript
复制
spring boot 2.1.8 (spring-boot-starter-data-jpa)

Spring引导完全忽略application.properties文件中的命名策略属性(其他属性运行良好)

在spring 2.1.8的源代码中,我找到了策略道具的名称,并将它们复制到属性中:

可以通过分别设置spring.jpa.hibernate.naming.physical-strategyspring.jpa.hibernate.naming.implicit-strategy属性来配置物理实现和隐式策略实现的完全限定类名。或者,如果ImplicitNamingStrategyPhysicalNamingStrategy bean在应用程序上下文中可用,则Hibernate将被自动配置为使用它们。但它不起作用。

谢谢。

application.properties

代码语言:javascript
复制
spring.application.name=file parser
driverClassName=org.sqlite.JDBC
url=jdbc:sqlite:C:\\Java\\ParseSite\\sample.db
user=admin
pass=123

#nothing works
spring.jpa.hibernate.naming.implicit-strategy=ru.laz.db.ImplicitNamingStrategyImpl
spring.jpa.hibernate.naming.physical-strategy=ru.laz.db.PhysicalNamingStrategyImpl
spring.jpa.properties.hibernate.physical_naming_strategy = ru.laz.db.PhysicalNamingStrategyImpl

spring.jpa.properties.hibernate.dialect = ru.laz.db.SQLitePrefs.SQLiteDialect

pom.xml

代码语言:javascript
复制
<?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>
    <properties>
        <spring.boot.version>2.1.8.RELEASE</spring.boot.version>
        <java.version>1.8</java.version>
    </properties>

    <groupId>ru.laz</groupId>
    <artifactId>parse-site</artifactId>
    <version>0.1.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>${spring.boot.version}</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.asynchttpclient</groupId>
            <artifactId>async-http-client</artifactId>
            <version>2.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>
        <dependency>
            <groupId>org.xerial</groupId>
            <artifactId>sqlite-jdbc</artifactId>
            <version>3.16.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.10</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

NewsBlockRepo.java

代码语言:javascript
复制
@Repository
public interface NewsBlockRepo extends CrudRepository<NewsBlock,Integer> {

    //only this method works ok
    @Modifying
    @Transactional
    @Query(value = "insert or replace into news_blocks (date, title, url, body, sent) values (:date, :title, :url, :body, :sent)", nativeQuery = true)
    void insertOrIgnore(@Param("date") String date, @Param("title") String title, @Param("url") String url, @Param("body") String body, @Param("sent") int sent);
}

NewsBlock.java

代码语言:javascript
复制
package ru.laz.db;


import javax.persistence.*;

@Entity
@Table(name = "news_blocks")
public class NewsBlock {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
    @Column(name = "date")
        private String date = "";//for unique constaint in sqlite
    @Column(name = "title")
        private String title = "";
    @Column(name = "url")
        private String url = "";
    @Column(name = "body")
        private String body = "";
    @Column(name = "sent")
        private int sent = 0;

    public long getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public int getSent() {
        return sent;
    }

    public void setSent(int sent) {
        this.sent = sent;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof NewsBlock)) {
            return false;
        }
        NewsBlock nb = (NewsBlock) o;
        return this.url.equals(nb.getUrl()) && this.title.equals(nb.getTitle()) && this.body.equals(nb.getBody() );
    }

    @Override
    public String toString() {
        return "date: " + date + " title: "+title + " url: " + url + " text: " + body;
    }
}

我的PhysicalNamingStrategyImpl

代码语言:javascript
复制
    public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl implements Serializable {

        public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();

        @Override
        public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
            String nameModified = name.getText();
            // Do whatever you want with the name modification
            return new Identifier(nameModified, name.isQuoted());
        }
}

甚至ImplicitNamingStrategyImpl

代码语言:javascript
复制
public class ImplicitNamingStrategyImpl extends ImplicitNamingStrategyJpaCompliantImpl {

        @Override
    protected Identifier toIdentifier(String stringForm, MetadataBuildingContext buildingContext) {
        return super.toIdentifier(stringForm, buildingContext);
    }
}

最终控制器从存储库调用方法

代码语言:javascript
复制
    @RequestMapping("/getUnsent")
    public String getUnsent() throws Exception {
        return objectMapper.writeValueAsString(newsBlockRepo.findAll());
    }

错误:

代码语言:javascript
复制
org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (no such column: newsblock0_.id)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-05 03:14:44

错误是no such column: newsblock0_.id。很明显,在news_block块表中,没有id,这意味着,spring引导在实体类中考虑了id,因为您声明了它。实体类与表大致相等。

它要求声明的所有变量必须在表中,但有时您声明的变量不需要在表中。所以你应该表示@Transient

@Transient注释用于指示字段不应持久化在数据库中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58238646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档