Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将不同记录的数据添加到单个记录中?_Java_Hibernate_Jakarta Ee_Hibernate Mapping - Fatal编程技术网

Java 如何将不同记录的数据添加到单个记录中?

Java 如何将不同记录的数据添加到单个记录中?,java,hibernate,jakarta-ee,hibernate-mapping,Java,Hibernate,Jakarta Ee,Hibernate Mapping,如果没有时间,请看一看示例 我有两种类型的用户,临时用户和永久用户 临时用户将系统用作来宾,只需提供他们的姓名并使用它,但系统需要跟踪他们 永久用户是指已注册且永久的用户 一旦用户为自己创建了一个永久记录,我需要将用户作为客人时跟踪的所有信息复制到他的永久记录中 课程如下: @Entity public class PermUser{ @Id @GeneratedValue private long id; @OneToMany private List

如果没有时间,请看一看示例

我有两种类型的用户,临时用户和永久用户

临时用户将系统用作来宾,只需提供他们的姓名并使用它,但系统需要跟踪他们

永久用户是指已注册且永久的用户

一旦用户为自己创建了一个永久记录,我需要将用户作为客人时跟踪的所有信息复制到他的永久记录中

课程如下:

@Entity
public class PermUser{
    @Id
    @GeneratedValue
    private long id;

    @OneToMany
    private List Favorites favorites;    
    ....

}

@Entity
public class Favorites {
    @Id
    @GeneratedValue
    private long id;

    @OneToMany (cascade = CascadeType.ALL)
    @LazyCollection(LazyCollectionOption.FALSE)
    private List <FavoriteItems> items;

    ...
 }

 @Entity
   public class FavoriteItems {
     @Id
     @GeneratedValue
     private long id;

     private int quantity;

     @ManyToOne
     private Ball ball;
     ..
   }


@Entity
public class TempUser extends PermUser{
    private String date;
    ....
}
*请注意,我需要找到一个解决方案,我不在乎是否尝试新的解决方案而不是克隆对象。


我有两个不同类的原因是
tempUser
几乎没有其他属性,我可能还需要将少数
tempUser
的收藏夹添加到一个
permUser
的收藏夹列表中。此外,如上所述,用户可能有许多不同的不相关的临时记录

对此进行建模的一个好方法是创建类似于
UserData
类的东西,以便
TempUser
has-a
UserData
PermUser
has-a
UserData
。您还可以使
TempUser
具有-a
PermUser
,尽管这将不太清楚。如果您的应用程序需要交替使用它们(这是您在使用继承时得到的),那么这两个类都可以实现一个接口,返回
UserData
(或者在第二个选项中,
getPermUser
,其中
PermUser
返回自身)


如果您真的想使用继承,最简单的方法可能是使用“每个类的表层次结构”将其映射,然后使用直接的JDBC直接更新鉴别器列。

从纯OO的角度来看,实例从一种类型变形为另一种类型,不管是否休眠,都没有意义。听起来您可能希望独立于对象的数据库表示重新考虑对象模型。例如,四轮驱动似乎更像是汽车的一种特性,而不是一种专门化

如果我遗漏了什么,请原谅,但我不认为
TempUser
PermUser
应该是不同的类
TempUser
扩展了
PermUser
,这是一种“is-a”关系。显然,临时用户不是一种永久用户。您的问题没有提供足够的信息来证明它们是不同的——也许它们是同一个类,并且差异可以表示为几个新属性?例如:

@Entity
public class User{
    @OneToMany(cascade = CascadeType.ALL)
    private List Favorites favorites;
    private boolean isTemporary;
    ....
}

某些控制器可以处理从临时到永久的“转换”,确保
istemporation=false
,并适当设置永久用户的其他属性。这将完全回避克隆问题,并使数据库更容易操作。

对于问题的第2部分:

您正在使用
CascadeType.ALL
作为
收藏夹
关系。这包括
CascadeType.REMOVE
,这意味着用户的删除操作将级联到该实体。因此,指定一个不包含
CascadeType.REMOVE的
CascadeType
值数组。
请参阅。

,因为我同意之前的意见,即如果可能,您应该重新评估这些实体,但如果不可能,我建议您从数据库返回一个普通用户,然后将该用户分类为PermUser或TempUser,这两者都是用户的扩展,基于某些标准的存在。

我也有同样的问题。我一直在阅读很多有趣的文章和问题,直到我有了足够的灵感

起初,我还希望为不同类型的用户提供子类。事实证明,这个想法本身就是一个设计缺陷:

不要使用继承来定义角色

更多信息请点击此处

将用户视为一个大容器,其中包含其他实体,如凭证、首选项、联系人、项目、用户信息等

记住这一点,您可以轻松地更改某些用户的能力/行为

当然,您可以定义许多用户可以扮演的角色。扮演相同角色的用户将具有相同的功能

如果您有许多相互依赖的实体/对象,那么您应该考虑一种构建机制/模式,以定义良好的方式设置特定的用户角色

一些想法:

如果你有一个供用户使用的建设者/工厂,那么你的另一个问题就不会那么复杂了

示例(非常基本,不要期望太多!)

public void changeUserRoleToPermanent(用户当前用户){
UserBuilder=新的UserBuilder();
builder.setRole(Role.PERMANENT);//builder在内部执行所有填充操作
//复制你想保留的东西
builder.setId(user.getId);
builder.setPrefences();
// ... 
用户newRoleUser=builder.build();
newRoleUser=entityManager.merge(newRoleUser);
entitymanager.detach(当前用户);
//删除旧东西
entityManager.remove(currentUser.getAccountInfo());//已更改为不同的实现。。。
}
我承认,这是一些工作,但一旦基础设施准备就绪,您将有许多可能性!你可以很快地“发明”新东西


我希望我能传播一些想法。我为我糟糕的英语感到抱歉。

我想说的可能不是OO,但希望会有效。我很高兴将PermUserTempUser分开。不要扩展它,也不要将它们绑定到is-a关系中。所以我将在数据库中有两个单独的表,一个用于TempUser,一个用于PermUser,从而将它们视为两个单独的实体。许多人会发现这是多余的。。但请继续阅读。。。我们都知道。。有时候冗余是好的。。所以现在

1) 我不知道
@Entity
public class User{
    @OneToMany(cascade = CascadeType.ALL)
    private List Favorites favorites;
    private boolean isTemporary;
    ....
}
public static <E>  E copyObject(E dest, E src, Class<?> c) throws IllegalArgumentException, IllegalAccessException{
  // TODO: You may want to create new instance of 'dest' here instead of receiving one as parameter
    if (!c.isAssignableFrom(src.getClass())) 
    {
        throw new IllegalArgumentException("Incompatible classes: " + src.getClass() + " - " + c);
    }
    if (!c.isAssignableFrom(dest.getClass())) 
    {
        throw new IllegalArgumentException("Incompatible classes: " + src.getClass() + " - " + c);
    }
    while (c != null && c != Object.class) 
    {
        for (Field aField: c.getDeclaredFields()) 
        {                   
            // We skip static and final
            int modifiers = aField.getModifiers();
            if ( Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) 
            {
                continue;
            }

            // We skip the fields annotated with @Generated and @GeneratedValue
            if (aField.getAnnotation(GeneratedValue.class) == null && 
                aField.getAnnotation(Generated.class) == null) 
            {

                aField.setAccessible(true);
                Object value = aField.get(src);
                if (aField.getType().isPrimitive() ||
                    String.class == aField.getType()    || 
                    Number.class.isAssignableFrom(aField.getType()) ||
                    Boolean.class == aField.getType()   ||
                    Enum.class.isAssignableFrom(aField.getType()))
                {
                    try
                    {
                        // TODO: You may want to recursive copy value too
                        aField.set(dest, value);
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }   
        }
        c = c.getSuperclass();  
    }

    return dest;
}
@MappedSuperclass
public abstract class User {
    @Id
    @GeneratedValue
    private long id;
    // Common properties and relationships...
@Entity
@Table(name="USER")
public class PermUser extends User {
  // Specific properties
}
@Entity
@Table(name="PERMANENT_USER")
public class PermUser extends User {
  public PermUser() {} // default constructor
  public PermUser(List<TempUser> userData) {
     final Set<Favorites> f = new LinkedHashSet<>();

     // don't set the id
     for(TempUser u : userData) {
        this.name = u.getName();
        // Shallow copy that guarants uniqueness and insertion order
        // Favorite must override equals and hashCode
        f.addAll(u.getFavorites());
     } 
     this.favorites = new ArrayList<>(f);
     // Logic to conciliate dates
  }
}
Mapper mapper = new DozerBeanMapper();
mapper.map(tempUser.getFavorites(), user.getFavorites());
<mapping>
  <class-a>my.object.package.TempUser</class-a>
  <class-b>my.object.package.PermUser</class-b>

  <!-- common fields with the same name will be copied by convention-->

  <!-- exclude ids and fields exclusive to temp
  <field-exclude> 
    <a>fieldToExclude</a> 
    <b>fieldToExclude</b> 
  </field-exclude>           

</mapping>