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