【问题标题】:Spring boot+Web mvc+JPA using CrudRepository giving issue on insert of a row using save method throwing EntityExistsExceptionSpring boot+Web mvc+JPA 使用 CrudRepository 在插入行时使用抛出 EntityExistsException 的保存方法给出问题
【发布时间】:2019-07-13 17:25:51
【问题描述】:

在 CRUD 操作中,Create 给出错误“具有相同标识符值的不同对象已与会话关联”其余所有(读取、更新和删除)工作正常。

我使用 oracle sql 作为数据库,并且还有一个产品实体,具有与类别类的多对一映射。 实体类

@Entity
public class Categories {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    public Categories() {
        super();
    }

    public Categories(Integer id,String name) {
        this.id=id;
        this.name=name;
    }
    public Categories(String name) {

        this.name=name;
    }
//with setters and getters
}

JSP 页面

<body onload="document.getElementById('name').disabled = true;document.getElementById('hidden').disabled = true;">

    <div align="center">
        <h4>Add or Modify or Delete Categories</h4>
        <form:form method="POST" action="/categories" modelAttribute="categories">
            <table>
                <tr>
                    <td><form:label path="name">Name</form:label></td>
                    <td>

                        <form:select path="name">
                            <form:option value="NONE" label="Select" />
                            <form:options items="${categoriesList}" />
                        </form:select>

                    </td>   
                </tr>
                <tr>
                    <td>Operations</td>
                    <td>
                        <input type="radio" name="Ops" value="Add" checked="checked" onclick="document.getElementById('name').disabled = true; document.getElementById('newName').disabled = false;document.getElementById('hidden').disabled = true;">Add</input><br/>
                        <input type="radio" name="Ops" value="Modify"  onclick="document.getElementById('name').disabled = false; document.getElementById('newName').disabled = false;document.getElementById('hidden').disabled = true;">Modify</input><br/>
                        <input type="radio" name="Ops" value="Delete"  onclick="document.getElementById('name').disabled = false; document.getElementById('newName').disabled = true;document.getElementById('hidden').disabled = false;">Delete</input><br/>                   
                    </td>
                </tr>
                <tr>
                    <td>Name</td>
                    <td><input type="text" name="newName" id="newName"/>
                        <input type="hidden" id="hidden" name="newName" value="dummy"/>
                    </td>
                </tr>
                <tr>
                    <td colspan="2"><input type="submit" value="Submit" /></td>
                </tr>
            </table>
        </form:form>
    </div>
</body>

控制器类

    @Controller
public class CategoriesController {
    @Autowired
    private CategoriesService cservice;

    @RequestMapping(value = "/categories", method = RequestMethod.GET)
    public ModelAndView categories() {
        // view name  model 
        ModelAndView modelAndView = new ModelAndView("categories", "categories", new Categories());
        return modelAndView;
    }

    @RequestMapping(value = "/categories", method = RequestMethod.POST)
    public String  opsOnCategories(@ModelAttribute("categories") Categories cat,@RequestParam("Ops") String ops,@RequestParam("newName") String name) 
    {
        if(ops.equals("Modify"))
        {
            cservice.modifyCategory(new Categories(Integer.parseInt(cat.getName()), name));
        }else if(ops.equals("Add"))
        {
            cservice.addCategory(new Categories(name));
        }else 
        {
            cservice.deleteCategory(Integer.parseInt(cat.getName()));
        }

        return "categories";
    }


    @ModelAttribute("categoriesList")
       public Map<String, String> getCategoryList() {
          Map<String, String> categoriesList = new HashMap<String, String>();
          List<Categories> ls=cservice.getAll();
          for(int i=0;i<ls.size();i++)
          {
              categoriesList.put(ls.get(i).getId().toString(), ls.get(i).getName());
          }
          return categoriesList;
       }
}

任何人都可以帮助解决这个问题。

上一个导致错误的原因

insert into CATEGORIES(ID,NAME) values (1,'Mobile');
insert into CATEGORIES(ID,NAME) values (2,'Laptop');

**为消除错误所做的更改*

insert into CATEGORIES(ID,NAME) values (hibernate_sequence.nextval,'Mobile');
insert into CATEGORIES(ID,NAME) values (hibernate_sequence.nextval,'Laptop');

【问题讨论】:

  • 我错过了提到我正在使用 import.sql 和一些插入查询,它没有使用 hibernate_sequence,因为 hibernate_sequence 中存在不匹配和插入的最新主键

标签: spring-boot spring-mvc spring-data-jpa


【解决方案1】:

我最初的猜测是 @Id @GeneratedValue 与 Oracle 数据库有问题。

你可以做几件事:

1- 尝试连接到任何其他数据库类型只是为了测试功能 - 这样您就可以排除无关紧要的情况

2- 尝试将@org.springframework.data.annotation.Id 与javax 持久化的@Id 一起使用

看起来像这样的东西

@Id
@org.springframework.data.annotation.Id
private Integer id;

3- 创建一个生成随机整数 Id 的类并使用注释 (@GenericGenerator & @GeneratedValue) 引用它

【讨论】:

  • 感谢您的帮助。我尝试将数据库更改为在 spring boot (H2) 提供的数据库中构建,但它给出了同样的问题。在执行第 2 步之后,我得到了运行时异常,即没有为实体指定标识符。如果在每次添加中获得唯一值,我怀疑第三个建议是否会有所帮助。
  • 关于选项#2:你应该同时拥有 javax 的注释 ID 和 spring 的 ID:我已经在上面编辑了我的答案
  • 感谢您的帮助。实际上我错过了提到我正在使用 import.sql 和一些插入查询,它没有使用 hibernate_sequence,因为 hibernate_sequence 和插入的最新主键不匹配。
猜你喜欢
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 2022-06-10
  • 2017-07-04
  • 1970-01-01
相关资源
最近更新 更多