[英]Field 'index_id' doesn't have a default value" when trying to use the primary_key as part of composite key in Hibernate
我正在使用 Hibernate 來更新 MySQL 數據庫中的數據。 我有兩個表索引和屬性,如下所述。
第一個表中的 index_id 不是自動生成的,我正在分配值。
當我嘗試將 index_id 作為屬性表中復合鍵的一部分時,我得到“字段 'index_id' 沒有默認值”。 我可以在 MySQL 中手動插入數據,但我的問題是我無法通過 Hibernate 代碼執行此操作。
CREATE TABLE index (
index_id BINARY(16),
index_name VARCHAR(225) NOT NULL ,
config VARCHAR(255) NOT NULL,
PRIMARY KEY (index_id)
);
CREATE TABLE properties (
index_id BINARY(16),
property_key VARCHAR(225) NOT NULL,
property_value VARCHAR(225) NOT NULL,
PRIMARY KEY (index_id, property_key),
FOREIGN KEY (index_id) REFERENCES index(index_id)
);
對應的類與 Hibernate 注釋相同。
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.util.Date;
import java.util.Set;
import java.util.UUID;
import com.sun.istack.NotNull;
@Entity
@Table(name = "index")
public class Index {
@Id
@Column(name = "index_id")
private UUID indexId;
@Column(name = "index_name")
private String indexName;
@Column(name = "config")
private String config;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "index_id")
private Set<Property> properties;
public Index() {}
}
其他帖子中建議的答案是使用自動生成的值,這不是我想要的。
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name = "properties")
public class Property implements Serializable {
private static final long serialVersionUID = 1881413500711441951L;
@Id
@Column(name = "property_key")
private String propertyKey;
@Id
@Column(name = "property_value")
private String propertyValue;
public Property() {}
public Property(String propertyKey, String propertyValue) {
this.propertyKey = propertyKey;
this.propertyValue = propertyValue;
}
}
hibernate.cfg.xml
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name = "hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/index?useSSL=false</property>
<property name="connection.username">###</property>
<property name="connection.password">###</property>
<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">1</property>
<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- dbcp connection pool configuration -->
<mapping class="com.learning.models.Index" />
<mapping class="com.learning.models.Property" />
</session-factory>
</hibernate-configuration>
HibernateUtil.java
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateUtil {
private static StandardServiceRegistry registry;
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
// Create registry
registry = new StandardServiceRegistryBuilder().configure().build();
// Create MetadataSources
MetadataSources sources = new MetadataSources(registry);
// Create Metadata
Metadata metadata = sources.getMetadataBuilder().build();
// Create SessionFactory
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Exception e) {
e.printStackTrace();
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
return sessionFactory;
}
public static void shutdown() {
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
我能夠解決這個問題。 我在索引 class 中給出了一對多的關系
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "index_id")
private Set<Property> properties;
問題是我必須在屬性 class 中使用 index_id 進行多對一映射。
我將屬性 class 更改如下。
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name = "properties")
public class Property implements Serializable {
private static final long serialVersionUID = 1881413500711441951L;
@Id
@Column(name = "property_key")
private String propertyKey;
@Id
@Column(name = "property_value")
private String propertyValue;
@Id
@ManyToOne
@JoinColumn(name ="index_id")
private Index index;
public Property() {}
public Property(String propertyKey, String propertyValue, Index index) {
this.propertyKey = propertyKey;
this.propertyValue = propertyValue;
this.index = index;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.