Hibernate - автоматически сохранять каждое отношение - PullRequest
0 голосов
/ 18 мая 2018

Может быть, это простой вопрос, но я не могу выяснить эту ситуацию отношений в 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);

Но просто пользователь сохраняется в базе данных - почему не все?Из-за ленивых загрузок по умолчанию?Может ли моя идея быть реализована каким-либо образом?

PS: Конечно, я знаю о решении сохранения каждой из сущностей, но я привык делать это в других средах, таких как nette или Django, поэтому я не могуубирайся из головы.

PPS: Я обнаружил, что проблема в CascadeType по умолчанию.Может ли он быть установлен глобально, например, в XML-файле конфигурации Hibernate?Это хорошая идея (с точки зрения производительности - она ​​сохраняется каждый раз на «суперперстере» или только в случае изменений)?

PPPS: Я также обнаружил (напротив Django), что я должен установить FK ex-post для каждого элемента, добавленного в коллекцию.Это естественно (из-за выбранного чистого типа набора), но для меня это ново.Какой подход вы бы порекомендовали мне?Требуется FK в качестве аргумента в конструкторе элемента Entity, например:

  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 голосов
/ 18 мая 2018

Согласно это и это вам нужно иметь это в файле 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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...