【问题标题】:Java Spring Hibernate Saving Duplicate Values to MySQL table is throwing errorJava Spring Hibernate将重复值保存到MySQL表会引发错误
【发布时间】:2017-11-14 09:52:29
【问题描述】:

我正在尝试使用 CrudRepository 将一些值保存到 MYSQL 数据库,但似乎不起作用。我已经尝试了以下指南https://spring.io/guides/gs/accessing-data-mysql/,它工作正常,但是当我试图对我的程序遵循相同的原则时,它似乎由于某种原因不起作用。

这是创建数据库的类,该表已正确创建:

 @Entity
 public class MeasurementPoint {

 @Id


 @JsonProperty("f1")
 private double f1;

 @JsonProperty("precison")
 private double precison;

 @JsonProperty("recall")
 private double recall;

 private String date;

 public MeasurementPoint(double f1, double precison, double recall, String 
 date)  {
     this.f1 = f1;
     this.precison = precison;
     this.recall = recall;
     this.date=date;
 }

 public double getF1() {
     return f1;
 }

 public double getPrecison() {
     return precison;
 }

 public String getDate() {
     return date;
 }
 public double getRecall() {
     return recall;
 }
}

这里是 MSQL 终端为创建的实体输出列:

+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| f1       | double       | NO   | PRI | NULL    | auto_increment |
| date     | varchar(255) | YES  |     | NULL    |                |
| precison | double       | NO   |     | NULL    |                |
| recall   | double       | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

这是我试图从以下位置向数据库添加值的类:

@Controller
public class DataChart {

private static final Logger logger= LoggerFactory.getLogger(DataChart.class);

@Autowired
private static MeasurementRepository measurementRepository;

@GetMapping(value = "/statementchart")
@ResponseBody
public List<Measurement> scoreChartData() {

    List<MeasurementPoint> needDataPoints = new ArrayList<>();
    List<MeasurementPoint> backgroundDataPoints = new ArrayList<>();
    List<MeasurementPoint> goalDataPoints=new ArrayList<>();
    needDataPoints.add(new MeasurementPoint(0.3, 0.5, 0.2,  "2017-11-19"));
    needDataPoints.add(new MeasurementPoint(0.7, 0.4, 0.15, "2017-11-12"));
    needDataPoints.add(new MeasurementPoint(0.5, 0.3, 0.10, "2017-11-15"));
    needDataPoints.add(new MeasurementPoint(0.6, 0.2, 0.05, "2017-11-18"));
    measurementRepository.save(needDataPoints);

    backgroundDataPoints.add(new MeasurementPoint(0.2, 0.4, 0.2, "2017-11-19"));
    backgroundDataPoints.add(new MeasurementPoint(0.4, 0.3, 0.15, "2017-11-12"));
    measurementRepository.save(backgroundDataPoints);
   //backgroundDataPoints.add(new MeasurementPoint(0.5, 0.2, 0.10, "2017-11-15"));
   //measurementRepository.save(backgroundDataPoints);

这是保存这些点的输出:

+-----+------------+----------+--------+
| f1  | date       | precison | recall |
+-----+------------+----------+--------+
| 0.2 | 2017-11-19 |      0.4 |    0.2 |
| 0.3 | 2017-11-19 |      0.5 |    0.2 |
| 0.4 | 2017-11-12 |      0.3 |   0.15 |
| 0.5 | 2017-11-15 |      0.3 |    0.1 |
| 0.6 | 2017-11-18 |      0.2 |   0.05 |
| 0.7 | 2017-11-12 |      0.4 |   0.15 |
+-----+------------+----------+--------+
6 rows in set (0.00 sec)

这是我的 CrudRepository 类:

public interface MeasurementRepository extends CrudRepository<MeasurementPoint,Long> {
}

已解决

保存这些点可以正常工作,但一旦我保存了注释掉的新 MeasurementPoint

//backgroundDataPoints.add(new MeasurementPoint(0.5, 0.2, 0.10, "2017-11-15"));
//measurementRepository.save(backgroundDataPoints);

我收到一条错误消息:我猜这与重复值有关,但我该如何解决?

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session :

我通过创建一个名为 id 并带有注释 @Id 的 long 类型字段来解决它,因为显然每个创建的对象都应该有一个唯一的 id,抛出的错误是因为对象有一些 id。 @GeneratedValue 确保每次创建新对象时都会为该对象提供一个唯一的 Id。

    @Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;

【问题讨论】:

    标签: java mysql database spring hibernate


    【解决方案1】:

    我认为数据没有保存是因为错误。你只需要检查日志。启用Hibernate SQL logs 并在此处检查insert 语句。

    1. 您将 f1 作为自动生成的列,但为其设置值。我也不确定double 列是否可以自动生成。

    2. Hibernate 需要一个默认构造函数。 MeasurementPoint 没有。

    这意味着java.lang.NullPointerException: null(DataChart.java:30) Spring 没有设置 measurementRepository 字段。尝试删除static 修饰符。

    这个org.hibernate.PersistentObjectException: detached entity passed to persist: 意味着您不应该使用save 方法指定f1

    【讨论】:

    • 我在底部的帖子中添加了错误消息,它指向 measureRepository.save 方法。 1)我将值设置为它?您的意思是使用 setter 为其设置值吗? 2)我添加了一个默认构造函数,仍然无法正常工作。
    • @Genesis 1. 不,Spring 应该设置该值,因为 Spring 应该为 save 方法生成代码。 2.这个错误以后可能会发生。
    • 现在我得到错误:org.hibernate.PersistentObjectException:分离的实体传递给持久化:它指向测量点类的特定方法分离实体传递给持久化:com.ibm.fk.textanalys。测量点;嵌套异常是 org.hibernate.PersistentObjectException:分离的实体传递给持久化:com.ibm.fk.textanalys.MeasurementPoint
    • @Genesis 您应该提供问题中错误的完整堆栈跟踪。可能更好地问另一个问题。
    • 检查日志可能是访问数据库有问题(检查用户权限/密码/数据库是否存在)
    【解决方案2】:

    我设法通过删除 @GeneratedValue(strategy=GenerationType.AUTO) 来解决它 显然,同时我也在通过代码插入 id (任何主键值)。 所以解决方法是:如果使用@GeneratedValue,请不要通过代码插入id

    【讨论】:

    • 如果您使用@GeneratedValue,手动设置Id应该不会造成任何问题,Spring Data应该可以处理这种情况,我认为Spring Data SimpleJpaRepository.save方法中存在错误,请您运行您以 Id 3.0 而不是 0.3 为例
    • @VitaliiMuzalevskyi 您的意思是在 crudrepository 中将数据类型从 double 更改为 integer?
    • 不,只是在你的例子中改变值,我有一些猜测)
    • @VitaliiMuzalevskyi 好的,所以我更改了 new MeasurementPoint(3.0, 5.0, 2.0, "2017-11-19") 我收到错误 org.hibernate.id.IdentifierGenerationException: unrecognized id type : double -> java.lang.Double 但这与注释有关:@GeneratedValue(strategy= GenerationType.AUTO) 如果我删除该注释它工作正常。
    【解决方案3】:

    也许你有这个问题是因为你在CrudRepository 中指定了错误的 ID 类型,你的实体的 ID 是 Double 类型但在存储库中是 Long。

    已编辑:

    看起来JpaRepositorysave 方法对双精度值有一些问题,因为我可以看到它总是调用persist 方法,但如果指定了Id,它应该调用merge

    要解决此问题,您可以创建自己的存储库实现来处理此问题。

    如果您有这种可能性,另一种解决方案是将您的 Id 类型更改为 Long。

    【讨论】:

    • 你的意思是你仍然得到org.hibernate.PersistentObjectException: detached entity passed to persist,还是其他一些例外?请同时添加所有堆栈跟踪。
    • 我在帖子中添加了堆栈跟踪
    • 能否请您尝试将示例中的 Id 值更改为某个整数(改为 3.0 而不是 0.3)
    • 我将 Id 类型更改为 Long 并且保存仍然有效,但没有重复值。
    • 更新帖子中的代码,了解它现在的样子
    猜你喜欢
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2019-05-15
    • 2019-04-05
    相关资源
    最近更新 更多