java - Hibernate不保存复杂对象

标签 java hibernate

我想使用 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/

相关文章:

java - Hibernate 5仍然忽略@Table注释来查找表

java - 提交表单时 Struts 2 Hibernate 空指针异常

java - Android:检测何时启用软键盘

Java 日历 'getTimeInMillis()' 导致所有 'isSet' 字段为真

java - 持久化对象在 Hibernate 架构中是什么意思?

java - 使用ResourceDatabasePopulator时如何正确转义Oracle列名?

java - 将 slf4j 与 c3p0 和 Hibernate 一起使用

在 PySpark 中使用 collect_list 时 Java 内存不足

用于验证名称的 Java 正则表达式

java - 将大型数组缓存到 SQLite - Java/Android