也许这是一个简单的问题,但我无法在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>
答案 0 :(得分:0)
根据this和this
您需要在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中)。