我想使用 hibernate 保存以下对象:
@Entity
@Table(name = "setting")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Setting
{
@Id
@Column(name = "id")
public String internalID;
@Column(name = "name")
public String name;
@Column(name = "type")
public String type;
@Column(name = "regex")
public String regex;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "setting",
joinColumns = {@JoinColumn(name = "parent_id")},
inverseJoinColumns = {@JoinColumn(name = "id")})
public Collection<Setting> children;
@JsonIgnore
@Column(name = "parent_id")
public String parentID;
@Column(name = "value")
public String value;
public Setting()
{
this.internalID = UUID.randomUUID().toString();
}
}
Hibernate 尝试保存它,但子对象似乎失败了。
创建 3 层深度的 Setting
对象时,仅保存前 2 层,忽略第三层。
除此之外,第二层仅保存internalID 和parentID,而将名称、类型和正则表达式保留在数据库中为空。
数据库保存函数:
public static void saveObject(Object obj)
{
if(sessionFactory == null)
init();
try(Session session = sessionFactory.openSession())
{
session.beginTransaction();
session.save(obj);
session.getTransaction().commit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
我错过了什么? 注释有误吗?
重现步骤:
public static void test()
{
Setting outer = new Setting();
outer.name = "Outer";
Setting inner = new Setting();
inner.name = "Inner";
outer.children = new ArrayList<>();
outer.children.add(inner);
saveObject(outer);
}
public static void saveObject(Object obj)
{
if(sessionFactory == null)
initDB();
try(Session session = sessionFactory.openSession())
{
session.beginTransaction();
session.save(obj);
session.getTransaction().commit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static SessionFactory sessionFactory;
private static void initDB()
{
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure() // configures settings from hibernate.cfg.xml
.build();
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Runtime.getRuntime().addShutdownHook(new Thread(() ->
{
StandardServiceRegistryBuilder.destroy(registry);
}));
}
使用 SQL:
CREATE SCHEMA `cosmos` ;
CREATE TABLE `cosmos`.`setting` (
`id` VARCHAR(64) NOT NULL,
`name` VARCHAR(256) NULL,
`type` VARCHAR(7) NOT NULL,
`regex` VARCHAR(512) NULL,
`value` VARCHAR(512) NULL,
`parent_id` VARCHAR(64) NULL,
PRIMARY KEY (`id`));
CREATE TABLE `cosmos`.`setting_relation` (
`id` VARCHAR(64) NOT NULL,
`parent_id` VARCHAR(64) NULL,
PRIMARY KEY (`id`));
和配置:
<hibernate-configuration>
<session-factory name="localConnection">
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property
name="hibernate.connection.url">
jdbc:mysql://localhost:3306/cosmos?useSSL=false
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hibernate.connection.password">
****
</property>
<!-- List of XML mapping files -->
<mapping class="se.mulander.cosmos.settings.model.Setting"/>
</session-factory>
</hibernate-configuration>
最佳答案
尝试@JoinTable(name = "setting_some_name"而不是@JoinTable(name = "setting"
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "setting_some_name",
joinColumns = {@JoinColumn(name = "parent_id")},
inverseJoinColumns = {@JoinColumn(name = "id")})
public Collection<Setting> children;
或者如果您想在同一个表上使用自连接来完成此操作,请执行以下操作:
@ManyToOne(optional = true)
@JoinColumn(name = "parent_id")
public Setting parent;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent" , cascade = {CascadeType.ALL})
public Collection<Setting> children;
关于java - Hibernate不保存复杂对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44856806/