我一直在研究使用Spring Boot和JPA / Hibernate将数据加载/更新到Maria DB中的工具。我想将数据加载到具有复合主键的表中。以下是我尝试过的
嵌入式主键类,它由两个主键(键和语言)组成
@Embeddable
public class MessageResourcePK implements Serializable {
/**
*
*/
private static final long serialVersionUID = -4226351093015653675L;
private String language;
private String key;
public MessageResourcePK() {}
public MessageResourcePK(String language, String key) {
super();
this.language = language;
this.key = key;
}
/**
* @return the language
*/
@Column(name = "LANGUAGE")
public String getLanguage() {
return this.language;
}
/**
* @param language the language to set
*/
public void setLanguage(String language) {
this.language = language;
}
/**
* @return the key
*/
@Column(name = "KEY")
public String getKey() {
return this.key;
}
/**
* @param key the key to set
*/
public void setKey(String key) {
this.key = key;
}
@Override
public boolean equals(Object obj) {
boolean resultat = false;
if (obj == this) {
resultat = true;
} else {
if (!(obj instanceof MessageResourcePK)) {
resultat = false;
} else {
MessageResourcePK autre = (MessageResourcePK) obj;
if (!this.language.equals(autre.language)) {
resultat = false;
} else {
if (!this.key.equals(autre.key)) {
resultat = false;
} else {
resultat = true;
}
}
}
}
return resultat;
}
@Override
public int hashCode() {
return (this.language + this.key).hashCode();
}
实际表类
@Entity
@Table(name = "MESSAGE_RESOURCE")
@IdClass(MessageResourcePK.class)
public class MessageResourceTable implements
Comparable<MessageResourceTable> {
/**
*
*/
private static final long serialVersionUID = -4226351093015653675L;
private String language;
private String key;
private String message;
/**
* @return the language
*/
@Id
@Column(name = "LANGUAGE")
public String getLanguage() {
return this.language;
}
/**
* @param language the language to set
*/
public void setLanguage(String language) {
this.language = language;
}
/**
* @return the key
*/
@Id
@Column(name = "KEY")
public String getKey() {
return this.key;
}
/**
* @param key the key to set
*/
public void setKey(String key) {
this.key = key;
}
/**
* @return the message
*/
@Column(name = "MESSAGE")
public String getMessage() {
return this.message;
}
/**
* @param message the message to set
*/
public void setMessage(String message) {
this.message = message;
}
@Override
public int compareTo(final MessageResourceTable o) {
return this.language.compareTo(o.getLanguage()) +
this.key.compareTo(o.getKey());
}
为此的存储库JPA
@Repository("MessageResourceService")
@Transactional
public interface MessageResourceService extends
JpaRepository<MessageResourceTable, MessageResourcePK>{
}
findAll方法工作正常,但是当我尝试使用save方法时,它将生成以下查询
update
message_resource
set
message=?
where
key=?
and language=?
但是在Maria DB中它不会执行,我在本地尝试了以下查询,效果很好
update message_resource m set m.MESSAGE = 'jjjj' where m.`KEY`='someKey' and
m.`LANGUAGE`='someLanguage'
由于生成的查询是错误的,因此会引发 SQLGrammarException ,因为键的前面应该有类似 m.key 的东西,对此有一些解决方案。请不要将此标记为重复,因为我搜索了stackoverflow,没有人像我一样遇到同样的情况。
application.properties文件
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = root
spring.datasource.password =
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen
database
spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.MariaDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = validate
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.current_session_context_class
=org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true