我正在练习/学习一些SpringBoot+JPA应用程序,并且在尝试保存到数据库表时不断遇到问题。
JPA似乎是自动生成表名的,尽管我已经提供了@table注释。
我有一个简单的POJO,标记为@Entity
@Entity
@Table(name="SongList")
public class SongList {
@Id
private Integer id;
private String album;
private String artist;
private String title;
//Getter and Setter Methods
}
一个扩展JPA CrudRepository 的接口
import org.springframework.data.repository.CrudRepository;
public interface songRepo extends CrudRepository<SongList,Integer> {
}
设置数据源属性的属性yml文件
spring:
datasource:
driverClassName : com.mysql.cj.jdbc.Driver
url : jdbc:mysql://localhost:3306/Songdb
username : root
password : learning
jpa:
hibernate.ddl-auto : update
generate-ddl : false
show-sql : true
最后是测试类:
@SpringBootTest
@RunWith(SpringRunner.class)
class DataJpaApplicationTests {
@Autowired
ApplicationContext context;
@Test
void saveSongs() {
songRepo repo = (songRepo) context.getBean(songRepo.class);
SongList songs = new SongList();
songs.setId(4);
songs.setTitle("High Hopes");
songs.setAlbum("Panic! At the Disco");
repo.save(songs);
}
}
在运行Test类时,我的测试失败,并出现错误:
ERROR:
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Caused by: java.sql.SQLSyntaxErrorException: Table 'songdb.song_list' doesn't exist
我的数据库表已经存在。该数据库名为Songdb(而非Songdb(,表为SongList。
我不确定要注入的表名"song_list"在哪里,也不确定为什么我的数据库名称是"songdb"而不是url中提供的"songdb"。
我在这里错过了什么?请帮忙!
这是因为您使用的是Spring引导提供的默认命名策略。Hibernate使用物理策略和隐式策略映射字段名。Hibernate使用物理命名策略将我们的逻辑名称映射到SQL表及其列。Spring Boot,为这两种策略提供默认值spring.jpa.hibernate.naming.physical-strategy
默认为org.springframework.Boot.org.jpa.hibernate.SpringPhysicalNamingStrategy,以及spring.jpa.hibernate.naming.implicit-strategy
默认为org.springframework.boot.org.jpa.hibernate.SpringImplicitMingStrategy
春季启动的默认命名策略是:
- 用下划线替换点
- 将骆驼案改为蛇案
- 小写表格名称
您可以通过设置属性来更改它,如:
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
对你来说,只要改变物理命名策略就能解决你的问题。您也可以使用org.hibernate.cfg.EJB3NamingStrategy
,它将保留所提供的表名。既然你知道了问题的原因,你就可以随心所欲地解决它了。
如果你想要更多的控制权,你可以自定义你想要的物理命名策略。阅读:Hibernate命名策略更改表名