0

I am trying to save some values to a MYSQL database using CrudRepository but doesnt seem to work. I have tried the following guide https://spring.io/guides/gs/accessing-data-mysql/ and it works fine but when iam trying to follow the same principle for my program it doesnt seem to work for some reason.

Here is the class iam creating a database for, The table gets created properly:

 @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;
 }
}

Here is the MSQL terminal outputting the columns for the entity created:

+----------+--------------+------+-----+---------+----------------+
| 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    |                |
+----------+--------------+------+-----+---------+----------------+

Here is the class iam trying to add values to the database from:

@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);

Here is the output from saving these points:

+-----+------------+----------+--------+
| 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)

Here is my CrudRepository class:

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

SOLVED

saving these points works fine but as soon i save that out-commented new MeasurementPoint

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

i get a error saying: I guess it has to do with duplicate values but how do i fix this?

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

I solved it by creating a field of type long called id with annotation @Id because apparently every object created should get a unique id, the error thrown is because objects had some id. @GeneratedValue makes sure that everytime a new object is created a unqiue Id is given to that object.

    @Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
Genesis
  • 55
  • 3
  • 13

3 Answers3

0

I think data is not saved because of errors. You just need to check logs. Enable Hibernate SQL logs and check insert statement there.

  1. You have f1 as autogenerated column, but set value to it. Also I am not sure that double column can be autogenerated.

  2. Hibernate needs a default constructor. MeasurementPoint doesn't have one.

This means java.lang.NullPointerException: null(DataChart.java:30) that Spring doesn't set measurementRepository field. Try to remove the static modifier.

This org.hibernate.PersistentObjectException: detached entity passed to persist: means that you shouldn't specify f1 using the save method.

v.ladynev
  • 19,275
  • 8
  • 46
  • 67
  • I added the eror message in the post at the bottom, it points to the measurementRepository.save method. 1) Iam setting the value to it? do you mean use a setter to set a value to it? 2) I added a default constructor, still not working. – Genesis Nov 14 '17 at 10:24
  • @Genesis 1. No. Spring should set that value, because of Spring should generate code for the save method. 2. This error can happen in the future. – v.ladynev Nov 14 '17 at 10:28
  • Now i get the error: org.hibernate.PersistentObjectException: detached entity passed to persist: which points at the measurementpoints class at that specific method detached entity passed to persist: com.ibm.fk.textanalys.MeasurementPoint; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.ibm.fk.textanalys.MeasurementPoint – Genesis Nov 14 '17 at 10:28
  • @Genesis You should provide a full stack trace of the error in the question. Probably better to ask another question for that. – v.ladynev Nov 14 '17 at 10:30
  • check logs maybe something's wrong with accessing the database (check user permissions / password / that the db exists) – ACV Nov 14 '17 at 10:42
  • @v.ladynev do you mean that i shouldnt use save method at all? – Genesis Nov 14 '17 at 11:40
  • @Genesis You can use it :) Looks like you already found a solution. – v.ladynev Nov 14 '17 at 12:08
  • @v.ladynev Ye i did find a solution but i updated the post with a new error, check it out please – Genesis Nov 14 '17 at 12:34
  • @v.ladynev The problem is that the repository interface dont have those methods... I can only do save i guess – Genesis Nov 14 '17 at 12:46
0

Maybe you have this problem because you specified wrong ID type in you CrudRepository, your entity has ID of Double type but in repository is Long.

Edited:

Looks like save method of JpaRepository have some problems with double values, as I can see it always call persist method but it should call merge if Id is specified.

To solve this you can create your own Repository implementation where you will handle this.

Another solution is to change your Id type to Long if you have such possibility.

0

I managed to solve it by removing @GeneratedValue(strategy=GenerationType.AUTO) apparently and at the same time I was inserting id (any primary key value) by code too. so the fix is: Do not insert id by code if using @GeneratedValue

Genesis
  • 55
  • 3
  • 13
  • Setting of Id manually shouldn't cause any problem if you are using `@GeneratedValue` Spring Data should handle this case, I think there is a bug in Spring Data `SimpleJpaRepository.save` method, can you please run you example with Id 3.0 instead of 0.3 – Vitalii Muzalevskyi Nov 14 '17 at 12:28
  • @VitaliiMuzalevskyi you mean changing the datatype from double to integer in the crudrepository? – Genesis Nov 14 '17 at 12:36
  • no, just change value in you example, I have some guess ) – Vitalii Muzalevskyi Nov 14 '17 at 12:37
  • @VitaliiMuzalevskyi Ok so i changed new MeasurementPoint(3.0, 5.0, 2.0, "2017-11-19") I get the error org.hibernate.id.IdentifierGenerationException: unrecognized id type : double -> java.lang.Double but that is with the annotation: @GeneratedValue(strategy= GenerationType.AUTO) If i remove that annotation it works fine. – Genesis Nov 14 '17 at 12:43