【问题标题】:Should I update bidirectional relation also in Java?我是否也应该在 Java 中更新双向关系?
【发布时间】:2013-04-27 21:36:57
【问题描述】:

假设我有 UserGroup 实体,并希望它们之间有一对多的关系。 IE。每个User 属于一个Group,而任何Group 可以包含多个Users。

集团实体:

@Entity
@Table(name="GroupTable")
public class Group {

    @Id
    @Column(name="Id")
    private long id;

    @Column(name="Name")
    private String name;

    @OneToMany(mappedBy="group")
    private Set<User> users;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<User> getUsers() {
        return users;
    }

    public void setUsers(Set<User> users) {
        this.users = users;
    }

}

和用户实体:

@Entity
@Table(name="User")
public class User {

    @Id
    @Column(name="Id")
    private long id;

    @ManyToOne
    @JoinColumn(name="GroupId")
    private Group group;

    @Column(name="Name")
    private String name;

    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }



}

以下是应用代码:

public class App_Tester_Hibernate_01 
{

    private static Logger log = LoggerFactory.getLogger(App_Tester_Hibernate_01.class);

    public static void main( String[] args )
    {
        Configuration configuration = new Configuration();
        configuration.configure();


        ServiceRegistry serviceRegistry;
        SessionFactory sessionFactory;

        serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        
        sessionFactory = configuration.buildSessionFactory(serviceRegistry);


        Session session;

        session = sessionFactory.openSession();
        session.beginTransaction();

        Group group;
        User user;

        group = (Group) session.byId(Group.class).load(1l);
        if( group == null ) {

            group = new Group();

            group.setId(1l);
            group.setName("Group #1");


            session.save(group);
        }

        log.info("Group.Users = {}", StringUtils.collectionToCommaDelimitedString(group.getUsers()));

        user = (User) session.byId(User.class).load(1l);
        if( user == null ) {

            user = new User();

            user.setId(1l);
            user.setName("Bob");
            user.setGroup(group);

            session.save(user);
        }

        log.info("Group.Users = {}", StringUtils.collectionToCommaDelimitedString(group.getUsers()));

        user = (User) session.byId(User.class).load(2l);
        if( user == null ) {

            user = new User();

            user.setId(2l);
            user.setName("Alice");
            user.setGroup(group);

            session.save(user);
        }

        log.info("Group.Users = {}", StringUtils.collectionToCommaDelimitedString(group.getUsers()));

        user = (User) session.byId(User.class).load(3l);
        if( user == null ) {

            user = new User();

            user.setId(3l);
            user.setName("Peter");
            user.setGroup(group);

            session.save(user);
        }

        log.info("Group.Users = {}", StringUtils.collectionToCommaDelimitedString(group.getUsers()));

        session.update(group);

        log.info("Group.Users = {}", StringUtils.collectionToCommaDelimitedString(group.getUsers()));

    session.getTransaction().commit();
    session.close();

    }
}

不幸的是,getUser() 总是返回 null。为什么?不是设置为相关用户的代表吗?我做错了什么?

我应该自己进行集合同步吗? Hibernate 不会自动填充字段吗?

更新 1

我的休眠配置如下:

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/tester_hibernate_01</property>
        <property name="connection.username">root</property>
        <property name="connection.password">sa</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>

        <property name="hibernate.query.substitution">true 1, false 0, yes 'Y', no 'N'</property>

        <property name="hbm2ddl.auto">create</property>

        <mapping class="test.Tester_Hibernate_01.Group"/>
        <mapping class="test.Tester_Hibernate_01.User"/>


    </session-factory>

</hibernate-configuration>

添加

    @OneToMany(mappedBy="group", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<User> users;

没有帮助。

更新 2

添加

Hibernate.initialize(group);

没有帮助,getUsers() 仍然返回 null。

【问题讨论】:

    标签: java hibernate one-to-many hibernate-onetomany bidirectional-relation


    【解决方案1】:

    有趣的示例:您正在使用 2 个事务,组实体在您保存用户时已分离,因此它不会被更新(实际上我很好奇如果 hibernate 可以弄清楚它是否已附加,我会不这么认为,如果你尝试让我知道)。您可能想要做的是将用户添加到组实体中的集合中,然后刷新它,以便在用户实体中分配 ID。但是,您需要添加对组实体 (http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-hibspec-cascade) 中的集合字段的适当级联注释,以使其正常工作

    【讨论】:

    • 如何附加组实体?
    • 跨越两个保存语句的事务。你也可以提交你的持久性配置(hibernate.cfg.xml 或你使用的任何东西)
    • 抱歉,我有 4 个保存语句。选择哪些?
    • group = (Group) session.byId(Group.class).load(1l); session.save(组); user = (User) session.byId(User.class).load(2l);会话.保存(用户); -------------- 而不仅仅是在用户上设置组,您应该在组上引入一个 addUser 方法,将用户添加到集合中并在需要的用户上设置组,因为这种关系是双向映射的
    • 那么,Hibernate 什么都不做?虽然我将关系映射为双向,但这是我实现双向性的责任吗?这就是问题所在。 hibernate 可能会自动或通过显式命令更新字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    相关资源
    最近更新 更多