java - 带有嵌入字段的列名无效
问题描述
在某些测试中,我有一个错误:
SqlExceptionHelper - Invalid column name 'contact_information_id'.
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement
在数据库中,我有一个primary_contact_information_id列。
当存储库尝试保存组织实体时会发生这种情况。在 Organization 类中有一个PrimaryContact字段,在PrimaryContact类中我有contactInformation字段。
该项目已从 java7 迁移到 java8,目前,我正在从 Hibernate 3 迁移到 Hibernate 5。
有一个命名策略 org.hibernate.cfg.ImprovedNamingStrategy,所以对于 hibernate 5,我使用了一个CustomNamingStrategy
public class CustomNamingStrategy extends PhysicalNamingStrategyStandardImpl {
public static final CustomNamingStrategy INSTANCE = new CustomNamingStrategy();
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
return new Identifier(addUnderscores(name.getText()), name.isQuoted());
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
return new Identifier(addUnderscores(name.getText()), name.isQuoted());
}
protected static String addUnderscores(String name) {
final StringBuilder buf = new StringBuilder(name.replace('.', '_'));
for (int i = 1; i < buf.length() - 1; i++) {
if (
Character.isLowerCase(buf.charAt(i - 1)) &&
Character.isUpperCase(buf.charAt(i)) &&
Character.isLowerCase(buf.charAt(i + 1))) {
buf.insert(i++, '_');
}
}
return buf.toString().toLowerCase(Locale.ROOT);
}
}
组织
@Entity(name = "Organisation")
@Table(name = "organisation", uniqueConstraints = {@UniqueConstraint(name = "organisation_name_udx", columnNames = {"name"})})
@EntityListeners(EntityCreateListener.class)
public class Organisation implements Serializable, PatientListEntity {
// Some fields here
@Embedded
@Valid
private PrimaryContact primaryContact;
// Some fields here
}
主要联系人
@Embeddable
public class PrimaryContact extends Person implements Serializable {
private static final long serialVersionUID = 1L;
@Valid
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "primary_contact_information_id")
private ContactInformation contactInformation;
}
联系信息
@Entity(name = "ContactInformation")
@Table(name = "contact_information")
@Data
@NoArgsConstructor
public class ContactInformation implements Serializable {
public static final int MAX_PHONENUMBERS = 5;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Valid
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id")
private Address address = new Address();
@RFCEmail
@Size(max = RFCEmailValidator.EMAIL_TOTAL_MAX_LENGTH)
private String email = "";
@Valid
@Embedded
@AttributeOverrides({@AttributeOverride(name = "number", column = @Column(name = "phone_number_0")),
@AttributeOverride(name = "type", column = @Column(name = "phone_type_0"))})
private PhoneNumber phoneNumber0;
@Valid
@Embedded
@AttributeOverrides({@AttributeOverride(name = "number", column = @Column(name = "phone_number_1")),
@AttributeOverride(name = "type", column = @Column(name = "phone_type_1"))})
private PhoneNumber phoneNumber1;
@Valid
@Embedded
@AttributeOverrides({@AttributeOverride(name = "number", column = @Column(name = "phone_number_2")),
@AttributeOverride(name = "type", column = @Column(name = "phone_type_2"))})
private PhoneNumber phoneNumber2;
@Valid
@Embedded
@AttributeOverrides({@AttributeOverride(name = "number", column = @Column(name = "phone_number_3")),
@AttributeOverride(name = "type", column = @Column(name = "phone_type_3"))})
private PhoneNumber phoneNumber3;
@Valid
@Embedded
@AttributeOverrides({@AttributeOverride(name = "number", column = @Column(name = "phone_number_4")),
@AttributeOverride(name = "type", column = @Column(name = "phone_type_4"))})
private PhoneNumber phoneNumber4;
@OneToOne
@JoinColumn(name = "time_zone_code")
private TimeZone timeZone;
}
如您所见,在contactInformation 字段下有一个@JoinColumn(name = "primary_contact_information_id"),但它没有帮助。
!!!更新 !!!
看起来这种奇怪的行为是由于我的自定义命名策略而发生的。所以,我决定完全删除它。但是现在,在添加必要@Column
的注释后,我收到了一个新错误:
BatchUpdateException: The UPDATE statement conflicted with the FOREIGN KEY constraint "application_dme_provider_fk1". The conflict occurred in database "ruslans_00_develop_dev_easycare", table "dbo.application", column 'application_code'.], SQL: update application_dme_provider set application_code=? where application_code=? and party_id=? and party_role_type_code=?
解决方案
该问题是由于 Hibernate 5 中的默认命名策略而发生的。它为每个(OneToOne、OneToMany、ManyToMany)关系添加了“_id”。
@JoinColumn(name = <correct_name_from_db>)
会修复它。
就我而言,还有一个没有JoinColumn注释的ContactInformation字段。
推荐阅读
- python - 在python中的条件下找到eqal项时拆分字符串列表
- android - 从 Firebase 获取数据 - FIRESTORE DB
- python - 如何在 django 中使用 Json 字段存储波斯字符?
- javascript - HTML 的三元 Javascript (Angular)
- amazon-web-services - 将 Github 操作与 codebuild 结合使用
- python - 未找到模块错误:找不到office365
- python - 使用python计算每个相邻字符的出现
- spring - 未能在 Spring Webclient 上添加客户端凭据(clientid/clientsecret):请求处理失败 ... 401 UNAUTHORIZED
- java - 使用“RestTemplate restTemplate”了解@MockBean 的用法
- visual-studio-code - 我正在尝试运行一个 java 文件,该文件读取同一目录中的文本文件,但它说找不到该文件