Spring 为什么Hibernate在破坏查询的字段名中添加了太多的反勾号?
我正在开发一个使用hibernate作为JPA提供者的spring引导应用程序。我使用内存中的H2数据库测试它时没有问题,但我必须在application.properties中添加Spring 为什么Hibernate在破坏查询的字段名中添加了太多的反勾号?,spring,hibernate,Spring,Hibernate,我正在开发一个使用hibernate作为JPA提供者的spring引导应用程序。我使用内存中的H2数据库测试它时没有问题,但我必须在application.properties中添加spring.jpa.properties.hibernate.globally_quoted_identifiers=true,因为其中一个表名是mysql中的保留关键字。 但是,Hibernate现在在标识符的中间添加了额外的回退,导致MySQL拒绝了错误的查询。以下是这样一个问题: select scoreca
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
,因为其中一个表名是mysql中的保留关键字。
但是,Hibernate现在在标识符的中间添加了额外的回退,导致MySQL拒绝了错误的查询。以下是这样一个问题:
select scorecard0_.`id` as id1_10_3_, scorecard0_.`default_role_`id`` as default_2_10_3_, scorecard0_.`game_`id`` as game_3_10_3_, robotrole1_.`id` as id1_8_0_, robotrole1_.`description` as descript2_8_0_, robotrole1_.`name` as name3_8_0_, robotrole1_.`scorecard_`id`` as scorecar4_8_0_, scorecard2_.`id` as id1_10_1_, scorecard2_.`default_role_`id`` as default_2_10_1_, scorecard2_.`game_`id`` as game_3_10_1_, game3_.`id` as id1_3_2_, game3_.`name` as name2_3_2_, game3_.`type` as type3_3_2_, game3_.`year` as year4_3_2_ from `scorecard` scorecard0_ left outer join `robot_role` robotrole1_ on scorecard0_.`default_role_`id``=robotrole1_.`id` left outer join `scorecard` scorecard2_ on robotrole1_.`scorecard_`id``=scorecard2_.`id` inner join `game` game3_ on scorecard0_.`game_`id``=game3_.`id` where scorecard0_.`game_`id``=?
您可能不需要对整件事进行详细说明,但是有几个例子是scorecard0.`default\u role\u`id`
和类似的,其中default\u role\u id
中的id
被额外引用了一段时间。有没有办法解决这个问题?或者我需要提交错误报告并等待
以下是查询中某些实体的类:
@Entity
public class Scorecard implements Identifiable<Long> {
@Id
@GeneratedValue
private long id;
@OneToOne(optional = false)
private Game game;
@OneToMany(cascade = CascadeType.PERSIST,mappedBy = "scorecard")
@NotEmpty(groups = {Default.class,Creating.class})
private Set<ScorecardSection> sections = new HashSet<>();
@OneToMany(mappedBy = "scorecard")
private Set<Result> results = new HashSet<>();
@OneToMany(cascade = CascadeType.PERSIST,mappedBy = "scorecard")
private Set<RobotRole> robotRoles = new HashSet<>();
@OneToOne(cascade = CascadeType.PERSIST)
private RobotRole defaultRole;
public Scorecard() {
}
public Scorecard(long id){
setId(id);
}
public Game getGame() {
return game;
}
public void setGame(Game game) {
this.game = game;
}
public Set<ScorecardSection> getSections() {
return sections;
}
public List<FieldSection> getFields() {
return sections.stream().filter(section -> section instanceof FieldSection)
.map(section -> (FieldSection) section).collect(Collectors.toList());
}
@Override
public Long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Set<Result> getResults() {
return results;
}
public Set<RobotRole> getRobotRoles() {
return robotRoles;
}
public Set<RobotRole> getRoles() {
return robotRoles;
}
public RobotRole getDefaultRole() {
return defaultRole;
}
public void setDefaultRole(RobotRole defaultRole) {
this.defaultRole = defaultRole;
}
public interface Creating{
}
}
@Entity
public class RobotRole {
@Id
@GeneratedValue
private long id;
@ManyToOne
@JsonIgnore
private Scorecard scorecard;
@OneToMany(mappedBy = "robotRole", cascade = CascadeType.ALL)
private Set<ScoreWeight> weights = new HashSet<>();
@NotNull
private String name;
private String description;
public RobotRole() {
}
public RobotRole(String name){
setName(name);
}
public Scorecard getScorecard() {
return scorecard;
}
public void setScorecard(Scorecard scorecard) {
this.scorecard = scorecard;
}
@AssertTrue
public boolean weightsMatchScorecard() {
return weights.stream().map(ScoreWeight::getField)
.map(ScorecardSection::getScorecard)
.allMatch(scorecard1 -> Objects.equals(scorecard1.getId(), scorecard.getId()));
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Set<ScoreWeight> getWeights() {
return weights;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@实体
公共类记分卡实现可识别的{
@身份证
@生成值
私人长id;
@OneToOne(可选=错误)
私人游戏;
@OneToMany(cascade=CascadeType.PERSIST,mappedBy=“记分卡”)
@NotEmpty(groups={Default.class,Creating.class})
private Set sections=new HashSet();
@OneToMany(mappedBy=“记分卡”)
私有集结果=新HashSet();
@OneToMany(cascade=CascadeType.PERSIST,mappedBy=“记分卡”)
私有集robotRoles=新HashSet();
@OneTONE(cascade=CascadeType.PERSIST)
私人机器人角色;
公共记分卡(){
}
公共记分卡(长id){
setId(id);
}
公共游戏getGame(){
回归游戏;
}
公共无效设置游戏(游戏){
这个游戏=游戏;
}
公共集getSections(){
回流段;
}
公共列表getFields(){
返回sections.stream().filter(section->section instanceof FieldSection)
.map(section->(FieldSection)节).collect(collector.toList());
}
@凌驾
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共集getResults(){
返回结果;
}
公共集getRobotRoles(){
返回机器人管;
}
公共集getRoles(){
返回机器人管;
}
公共RobotRole getDefaultRole(){
返回默认角色;
}
public void setDefaultRole(RobotRole defaultRole){
this.defaultRole=defaultRole;
}
公共接口创建{
}
}
@实体
公营机甲{
@身份证
@生成值
私人长id;
@许多酮
@杰索尼奥雷
私人记分卡;
@OneToMany(mappedBy=“robotRole”,cascade=CascadeType.ALL)
私有集权重=新HashSet();
@NotNull
私有字符串名称;
私有字符串描述;
公共RobotRole(){
}
公共RobotRole(字符串名称){
集合名(名称);
}
公共记分卡getScorecard(){
回报记分卡;
}
公共作废记分卡(记分卡){
这个。记分卡=记分卡;
}
@资产真实
公共布尔权重MachsCoreCard(){
返回weights.stream().map(ScoreWeight::getField)
.map(记分卡部分::getScorecard)
.allMatch(记分卡1->Objects.equals(记分卡1.getId(),记分卡.getId());
}
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共集getWeights(){
返回权重;
}
公共字符串getDescription(){
返回说明;
}
公共void集合描述(字符串描述){
this.description=描述;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
}
注意:启用此选项后,Hibernate应该执行的操作是将默认角色id转换为默认角色id`。正在发生的是
`default\u role\u`id`
。请注意id
周围额外的反勾号。它们不应该在那里。我认为这正是hibernate.global\u quoted\u identifiers=true所做的
但由于1个表存在问题,您可以使用不同的解决方案,如:
@Entity
@Table(name="\"User\"")
public class User {
...
}
这将在保留关键字表的周围添加反勾号。这是hibernate中的一个错误,在我使用的hibernate版本(5.0.9)之后修复。我会尝试修改版本号,这样我就可以使用一个版本,在这个版本中,这个错误是固定的,不会与其他依赖项冲突
编辑:与spring合作的hibernate的最新版本是5.0.12,它没有这个bug。我可能会提出一个新问题,关于是否/如何在spring中使用hibernate 5.1.x或5.2.x。我无法在注释中正确显示标记。我要给这个问题加一条注释。