【问题标题】:Assign existing child entity for parent entity JPA- GAE为父实体 JPA-GAE 分配现有子实体
【发布时间】:2014-06-03 21:51:51
【问题描述】:

我有 2 个实体,它们之间有关系。

这两个实体都已创建并插入到数据库中。 在某些时候,用户有能力在它们之间建立联系。 当我尝试这样做时,我得到:

javax.persistence.PersistenceException:检测到尝试建立 WannaMeetUser("654321") 作为 WannaMeetUser("123456") 的父级,但是 WannaMeetUser("123456") 标识的实体已经被 在没有父母的情况下坚持。无法建立或更改父级 一旦一个对象被持久化。

这是一个传递关系(用户可以有很多朋友来自用户之王):

附上代码:

    @Entity 
    public class WannaMeetUser {

        @Id //signifies the primary key
        @Column(name = "ID", nullable = false)
        private Key id;

          @ManyToMany
          @Basic
          private List<WannaMeetUser> userFriends = new ArrayList<WannaMeetUser>();
}

public void addFriendToWannaMeetUser(@Named("userId") String userId,
            @Named("friendId") String friendId) {
        EntityManager mgr = getEntityManager();
        try
        {
            WannaMeetUser user = mgr.find(WannaMeetUser.class, WannaMeetServerUtils.getKeyFromString("WannaMeetUser", userId));
            WannaMeetUser friend = mgr.find(WannaMeetUser.class, WannaMeetServerUtils.getKeyFromString("WannaMeetUser", friendId));
            String coupleId = getcoupleId(userId.toString(), friendId.toString());
            if (friend == null || user == null) {
                throw new EntityNotFoundException("Object does not exist");
            }
            WannaMeetCouple couple=mgr.find(WannaMeetCouple.class, coupleId);
            if (couple == null) {
                couple = createCouple(userId.toString(), friendId.toString());
                couple.setId(coupleId);
                setUserJoined(couple, userId.toString(), friendId.toString(), true);
            }
         else {
            if (isFriendAllready(couple, userId.toString(), friendId.toString()))
                ;
            setUserJoined(couple, userId.toString(), friendId.toString(), false);
            doAddFriend(user, friend, 10, 12321321);
            mgr.persist(couple);
            mgr.persist(friend);
            mgr.persist(user);
        }

        } catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            mgr.close();
        }

    }

我的问题是建立这种关系的最佳方式是什么?

谢谢

【问题讨论】:

    标签: java google-app-engine jpa


    【解决方案1】:

    消息说用户 1 已经在没有任何父级的情况下被持久化,但现在我们尝试 将用户 2 保留为用户 1 的父级,但已知用户 1 没有父级。

    尝试使用级联来一次性持久化所有内容。你可以像这样声明一个级联关系:

    @ManyToMany(cascade=CascadeType.ALL)
    private List<User> userFriends;
    

    然后使用级联一次性持久化所有内容:

    User user1 = new User();
    User user2 = new User();
    
    user1.getUserFriends().add(user2);
    
    // this persists the whole tree in one go
    entityManager.persist(user1);
    

    【讨论】:

    • 感谢您的评论,但在创建用户时不知道关系,因此您的建议与我无关。
    【解决方案2】:

    父子实体应仅用于永不改变的关系(例如用户和他的照片)。对于动态关系,您有以下三种选择:

    (A) 将对其他对象的引用存储为属性(例如,用户实体中的 userFriends 属性)。如果关系是单向的(例如用户 A 喜欢用户 B),那么您只能更新一个实体。对于双向关系,您更新两个实体。

    (B) 使用两个属性 User A 和 User B 创建一个新的实体类型关系。根据需要创建和删除这些实体。

    (C) 当用户 A 喜欢用户 B 时,创建一个新的实体关系作为用户 A 的子实体,并使用用户 B 的 id 作为此新关系实体的 id。

    这些选项之间的选择取决于您的数据模型和数据访问模式。

    【讨论】:

    • 感谢您的帮助,关于选项 A,您的意思是使用没有 @ManyToMany 注释的属性吗?
    • 我不熟悉 JPA 如何映射到 Datastore API。看看stackoverflow.com/questions/8036420/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 2011-12-19
    • 2017-03-15
    • 1970-01-01
    相关资源
    最近更新 更多