Java 如何避免在JPA Hibernate中一对多更新父级

Java 如何避免在JPA Hibernate中一对多更新父级,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我做了一个使用spring+hibernate(JPA映射)的项目。我正在使用一对多JPA Hibernate。我不知道我的设计本身是错还是错。我有两个类Useradmin(Parent)和Tanya(child)。由此,我需要使用Useradmin(parent)的属性从另一个表中获取记录。当我为Tanya(孩子)插入新记录时,Useradmin(家长)也更新了。我只想插入Tanya(child)而不插入或更新Useradmin(Parent)。有谁能给我一个解决方案,请提出继续进行的想法:)

我做了一个使用spring+hibernate(JPA映射)的项目。我正在使用一对多JPA Hibernate。我不知道我的设计本身是错还是错。我有两个类Useradmin(Parent)和Tanya(child)。由此,我需要使用Useradmin(parent)的属性从另一个表中获取记录。当我为Tanya(孩子)插入新记录时,Useradmin(家长)也更新了。我只想插入Tanya(child)而不插入或更新Useradmin(Parent)。有谁能给我一个解决方案,请提出继续进行的想法:)

这是我的Useradmin类:

@SuppressWarnings("serial")
@Entity
@Table(name="user")
public class UserAdmin implements Serializable{

@Id
@Column(name="no_dana", unique=true, nullable=false, updatable=false)
private String no_dana;

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

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

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

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

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

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

@OneToMany(cascade=CascadeType.ALL, mappedBy="useradmin")
private Set<Tanya> tanya  = new HashSet<Tanya>(0);

/**other field**//

/**setter and gettter methods**/
}
这是我的控制器:

@RequestMapping("/user/tanya-jawab.html")
public ModelAndView listTanyaJawab(ModelMap model)throws Exception
{
    User user           = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    String sessionUser  = user.getUsername();

    try{
        UserAdmin dataUser = userService.get(sessionUser);
        model.addAttribute("userData", dataUser);
    } catch(Exception e){
        e.printStackTrace();
    }

    ModelAndView mav = new ModelAndView("usr-tanya");
    List<Tanya> tanyajawab = tanyaService.listAllTanya();
    mav.addObject("tanyajawab", tanyajawab);
    return mav;
}

@RequestMapping(value="/user/add-tanya-jawab.html", method=RequestMethod.POST)
public ModelAndView addTanyaJawab(@ModelAttribute Tanya tanya, ModelMap model, HttpServletRequest request, HttpServletResponse response)throws Exception
{
    String userName = request.getParameter("hiddenUsername");

    UserAdmin useradmin = new UserAdmin();
    useradmin.setNo_dana(userName);
    System.out.println("ini"+userName);     
    java.util.Date date = new java.util.Date();

    tanya.setUseradmin(useradmin);
    tanya.setCreated(date);
    tanyaService.save(tanya);       

    return listTanyaJawab(model);
}
@RequestMapping(“/user/tanya jawab.html”)
公共模型和视图列表Tanyajawab(模型映射模型)引发异常
{
User User=(User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
字符串sessionUser=user.getUsername();
试一试{
UserAdmin dataUser=userService.get(sessionUser);
model.addAttribute(“userData”,dataUser);
}捕获(例外e){
e、 printStackTrace();
}
ModelAndView mav=新ModelAndView(“usr tanya”);
List tanyajawab=tanyaService.listAllTanya();
mav.addObject(“tanyajawab”,tanyajawab);
返回mav;
}
@RequestMapping(value=“/user/add tanya jawab.html”,method=RequestMethod.POST)
public ModelAndView addTanyaJawab(@ModelAttribute Tanya Tanya,ModelMap model,HttpServletRequest请求,HttpServletResponse响应)引发异常
{
字符串userName=request.getParameter(“hiddenUsername”);
UserAdmin UserAdmin=new UserAdmin();
useradmin.setNo_dana(用户名);
System.out.println(“ini”+用户名);
java.util.Date Date=新建java.util.Date();
tanya.setUseradmin(useradmin);
tanya.setCreated(日期);
tanyaService.save(tanya);
返回列表Tanyajawab(型号);
}

任何帮助都将是我的荣幸:)

如果我理解正确的话,这个问题似乎发生在您的

public ModelAndView addTanyaJawab(@ModelAttribute Tanya tanya, ModelMap model, HttpServletRequest request, HttpServletResponse response)throws Exception {...}
方法。您正在创建一个新的Useradmin对象,其中包含:

    UserAdmin useradmin = new UserAdmin();
问题是这个对象是新的,尚未持久化到数据库中。创建新的Tanya对象时,将其引用到新的UserAdmin对象。然而,这并不存在


您需要在事先从数据库加载的Tanya对象中设置一个持久的UserAdmin对象,或者创建一个新的UserAdmin对象,添加Tanya并保存该对象。

有几件事可以修改(尽管这不是一个好主意,除非是在测试环境中):

  • 如注释区域中所述,从
    @ManyToOne
    注释中删除
    级联
    属性
  • 不要将
    useradmin
    设置为
    tanya
    对象,如下所示:

    tanya.setUseradmin(useradmin);
    
tanya
对象保存到数据库之前。否则,持久性提供程序将抛出
非法状态异常
,因为
级联
属性被删除。这是合乎逻辑的,因为您的
Tanya
实体包含
UserAdmin
实体的外键。提供者在保存
Tanya
之前,必须检查数据库中是否有
UserAdmin
的条目

但是您创建了一个新的
UserAdmin
实例,如下所示:

UserAdmin useradmin = new UserAdmin();
因此,数据库中没有条目。因此,提供程序无法将指向数据库中不存在的
useradmin
条目的
tanya
保存到数据库中

以及一些改进代码的建议:

  • 删除不必要的
    @列
    注释,只要不修改默认值,例如在

    @Column(name="isi")
    private String isi;
    
    它是无用的,因为它是默认行为

  • 为什么
    @superswarnings
    注释?这是不必要的

  • 最后,在真实环境中,以下情况是非常危险的:

    cascade = CascadeType.ALL
    
    尤其是级联型。移除


从中的userAdmin中删除级联Tanya@aviad给我这个错误
org.springframework.dao.InvalidDataAccessResourceUsageException:无法执行查询;SQL
我不知道为什么会这样。尝试通过用户名获取UserAdmin,然后将其设置为tanya?@aviad面临另一个错误~我该怎么做?您需要从数据库获取UserAdmin实例。查看您的代码,我猜您是通过查询参数传入用户名的。这很好,因为您对字段no_dana的UserAdmin实体有一个唯一的约束。但是我建议您应该使用实体ID,因为这就是它的用途。让id/no_dana从那里查询数据库以加载UserAdmin实例,在您的Tanya实例中设置加载的对象并保存Tanya实例进入此代码
UserAdmin UserAdmin=(UserAdmin)userService.get(userName)。。。。瞧,D
cascade = CascadeType.ALL