Hibernate - 自动保持每个关系

时间:2018-05-17 22:59:08

标签: java hibernate

也许这是一个简单的问题,但我无法在Hibernate中找到这种关系的情况。

我有这些实体:

@Entity
public class User {
  ...
  @OneToMany(mappedBy = "user")
  private Set<Conversation> posts = new HashSet<Conversation>();
  ...
}

@Entity
public class Conversation { 
  ...
  @OneToMany(mappedBy = "conversation")
  private Set<Message> messages = new HashSet<Message>();
  ...
}

@Entity
public class Message { ... }

然后我想立刻创建具有对话和消息的用户。想法应该是这样的:

User user = new User();
     user.getPosts().add(new Conversation(){
        {
            getMessages().add(new Message());
        }
     });

session.persist(user);

但只是用户被保存在数据库中 - 为什么不是这样呢?因为默认的LAZY取货?我的想法能以某种方式实施吗?

PS:当然我知道坚持每个实体的解决方案,但我习惯在nette或Django等其他框架中这样做,所以我无法摆脱困境。

PPS:我发现问题是默认的CascadeType。它可以在全球范围内设置,例如在Hibernate配置XML?这是一个好主意(从绩效的角度来看 - 它每次都持续存在于#34; superpersist&#34;或者仅在变化的情况下)?

PPPS:我也发现(与Django相反)我必须为添加到集合中的每个项目设置FK事后。这很自然(因为选择了纯粹的Set类型),但对我来说是新的。你会推荐我哪种方法?在项目实体的构造函数中必需的FK作为参数,例如:

  Class Message{
    Message(Conversation conversation){
       setConversation(conversation);
    }
    ...
  }

或制作添加FK设置的方法,例如:

  Class Conversation{
    ...
    public void addMessage(Message msg){
       msg.setConversation(this);
       getMessages().add(msg);
    }
    ...
  }

制作会话+配置XML。

private final static String CFG = "hibernate-cfg.xml";
    private final static String SCRIPT_FILE = "query.sql";

    private static SessionFactory sessionFactory;

    private static ServiceRegistry buildRegistry() {
        return new StandardServiceRegistryBuilder()
                .configure(CFG)
                .build();
    }

    private static Metadata getMetaData() {
        return new MetadataSources(buildRegistry()).getMetadataBuilder().build();
    }

    private static SessionFactory buildSessionFactory() {
        return getMetaData().getSessionFactoryBuilder().build();
    }

    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null) {
            sessionFactory = buildSessionFactory();
        }
        return sessionFactory;
    }

    public static Session getSession(){
        try {
            return getSessionFactory().openSession();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

和hibernate-cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
    <property name="connection.url">
            jdbc:mysql://localhost:3306/learnme
        </property>
    <property name="connection.username">root</property>
    <property name="connection.password"/>
    <property name="connection.pool_size">100</property>
    <!-- SQL dialect -->
    <property name="hibernate.dialect">
            org.hibernate.dialect.MySQL5Dialect
        </property>
    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>
    <!-- Disable the second-level cache -->
    <property name="cache.provider_class">
            org.hibernate.cache.NoCacheProvider
        </property>
    <!-- Display all generated SQL to stdout -->
    <property name="show_sql">true</property>
    <!-- Drop and re-create the database schema on startup -->
    <property name="hbm2ddl.auto">update</property>
    <mapping class="learnme.hibernate.entities.User"/>
    <mapping class="learnme.hibernate.entities.Conversation"/> 
    <mapping class="learnme.hibernate.entities.Message"/>
  </session-factory>
</hibernate-configuration>

1 个答案:

答案 0 :(得分:0)

根据thisthis 您需要在persistence.xml文件中将其设置为全局设置:

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
   <persistence-unit-metadata>
     <persistence-unit-defaults>
       <cascade-persist/>
     </persistence-unit-defaults>
   </persistence-unit-metadata>
</entity-mappings>
  

映射文件必须位于默认位置,   META-INF / orm.xml,或显式指定的其他位置   在持久性单元定义中(在persistence.xml中)。