正如标题所示,我正在使用 Spring Boot 和 Hibernate 作为数据访问层构建一个 Web 应用程序,并且开发是在 InteliJ IDEA 14.1.2 上完成的。
我的知识
这是我第一次使用 Spring Boot、Hibernate 和 InteliJ。我已经构建了一些小应用程序来测试 Spring Boot 和 Hibernate,但这些应用程序与我现在构建的应用程序之间的复杂性差异有点大。
环境
关于我的环境,以防万一,我在托管 Redis 3.0.1 服务器的 VirtualBox 4.3.26 VM 上运行 Windows 7 SP1 64 位、MySQL 服务器 5.6.17、InteliJ 14.1.2 和 Ubuntu Server 14.04。
目的
此时使用上述技术的目的是将不同实体存储和检索到MySQL数据库(Redis仅用于 session 外部化和应用程序实例之间的共享)。换句话说,我正在构建我的数据访问层。
数据库
我的完整数据库架构可以在这里找到:
https://dl.dropboxusercontent.com/u/49544122/so/DB.pdf
来源
我的 Spring Boot 应用程序如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import se.domain.cvs.abstraction.dataaccess.AccountRepository;
import se.domain.cvs.domain.AccountEntity;
@SpringBootApplication
@EnableRedisHttpSession
public class Application implements CommandLineRunner {
@Autowired
AccountRepository repository;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... strings) throws Exception {
System.out.println("=======================================================");
AccountEntity account = repository.findByEmail("r.franklin@companya.se");
System.out.println("My name is " + account.getFirstName() + " " + account.getLastName());
System.out.println("=======================================================");
}
}
我使用 CommandLineRunner 接口(interface)只是为了测试裸数据访问层,尚未引入 REST 端点。
我的配置如下(YAML 格式):
...
# MySQL Database Configuration
spring.datasource:
url: jdbc:mysql://localhost:3306/cvs
username: cvs
password: cvs
driverClassName: com.mysql.jdbc.Driver
spring.jpa:
database: MYSQL
show-sql: true
hibernate.ddl-auto: validate
hibernate.naming-strategy: org.hibernate.cfg.DefaultNamingStrategy
properties.hibernate.dialect: org.hibernate.dialect.MySQL5Dialect
...
JPA 实体是使用 InteliJ 自动生成的,这就是问题开始的地方。让我们以下面的 OrderEntity 为例(为了简洁起见,我省略了一些代码):
...
@Entity
@Table(name = "order", schema = "", catalog = "cvs")
public class OrderEntity {
...
private int invoiceId;
...
private InvoiceEntity invoiceByInvoiceId;
...
@Basic
@Column(name = "InvoiceID", nullable = false, insertable = false, updatable = false)
public int getInvoiceId() {
return invoiceId;
}
public void setInvoiceId(int invoiceId) {
this.invoiceId = invoiceId;
}
...
@ManyToOne
@JoinColumn(name = "InvoiceID", referencedColumnName = "InvoiceID", nullable = false)
public InvoiceEntity getInvoiceByInvoiceId() {
return invoiceByInvoiceId;
}
public void setInvoiceByInvoiceId(InvoiceEntity invoiceByInvoiceId) {
this.invoiceByInvoiceId = invoiceByInvoiceId;
}
...
}
当尝试运行 Spring Boot 应用程序时,出现以下错误:
org.hibernate.MappingException: Repeated column in mapping for entity: OrderEntity column: invoiceId (should be mapped with insert="false" update="false")
经过一些研究,我猜问题是现在有两种方法可以设置发票ID,一种是通过 setInvoiceID()
setter ,另一种是通过 InvoiceEntity
与 OrderEntity 相关的对象本身,这可能会导致不一致的状态。正如这里的另一位用户所说,
You would do that when the responsibility of creating/udpating the related entity in question isn't in the current entity.
请参阅此处的相关帖子:Please explain about: insertable=false, updatable=false
将相应字段的建议值(insertable
和 updateable
)设置为 false 可修复错误。
我的问题是为什么这个生成方式是错误的?我的更改修复了错误,但我想确保我的 SQL 中没有错误导致 InteliJ 以错误的方式生成此错误。完整的 SQL 脚本可以在这里找到 http://pastebin.com/aDguqR1N .
此外,在生成实体时,InteliJ 需要一个 Hibernate 配置文件,我猜 Spring Boot 会在其他地方自行生成该文件(或使用基于 Java 的配置)。无论我将其留在那里还是删除它,它似乎都不会影响该应用程序。我猜想 SB 读取属性的顺序会覆盖它。我可以直接删除它吗?
非常感谢您的宝贵时间和提前提供的帮助,对这篇长文章表示歉意! :)
最佳答案
我的建议是让 Spring/Hibernate 为您生成数据库模式(包括外键和约束在内的所有内容都可以由 Spring 生成。
对我来说,以下方法有效:
在父实体中(在我的例子中是 TblUser):
@OneToMany(targetEntity=TblTracks.class,fetch=FetchType.EAGER,cascade=CascadeType.ALL,mappedBy="tbluser")
private List<TblTracks> tbltracks= new ArrayList<TblTracks>();
其中mappedBy指向子实体的Tbluser实体(私有(private)TblUser tbluser)
在子实体中(在我的例子中是 TblTracks),例如
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="idTblUser",nullable=false)
private TblUser tbluser;
关于mysql - 如何使用 IntelliJ 正确设置 Spring Boot 和 Hibernate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30140922/