0

I am using spring-data and hibernate for creating tables and inserting Data. From different threads i found that save method from JPARepository (From CRUDRepository) will only update the record if the record already exists. Below is one of the thread i found some information:

https://stackoverflow.com/a/40608937/10356053

I have an Entity which is duplicating the records (jpa is considering as a new insert even if the Object is same). I am not really sure whats happening or a Solution for this issue. Any suggestions are appreciated. Below is the Entity i have created:

CustomerEntity.java:

@Getter
@Setter
@Table(name = "Customers")
@Entity
public class CustomersEntity extends BasicEntity {
      @Id
     @GeneratedValue(generator = "UUID")
     @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
     @Column(name = "CustomerId", updatable = false, nullable = false)
     private UUID customerid;

     //and some other fields
}

BasicEntity.java:

@Getter
@Setter
public class BasicEntity implements serializable {
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_at", updatable = false)
    @CreatedDate
    private Date createdAt;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "updated_at")
    @LastModifiedDate
    private Date updatedAt;
}

Repository.java

@Repository
public interface Repositorty extends JpaRepository<CustomersEntity, UUID> {


}

When we are trying to save the above entites:

repository.save(customerEntity)

will persist as a new record in the database. Any suggestions are helpful. I am thinking is this because of the createdTime and updatedTime from the parent class? If yes, how do we avoid this? TIA.

ging
  • 219
  • 7
  • 20
  • probably because of new id for each record `UUID customerid;` if you want to update record then you have have the same `id` – Ryuzaki L Sep 17 '19 at 21:07
  • @Deadpool if my understanding is correct, jpa will check for equality before creating a new UUID ? if the object is same it should just update the record instead of creating the new record? Can you please correct me if i am wrong? – ging Sep 17 '19 at 21:09
  • I'm not sure, but you can try with existing id and see is it updating or not @ging – Ryuzaki L Sep 17 '19 at 21:11
  • @Deadpool no its just creating a new row in the DB. – ging Sep 17 '19 at 21:11
  • is the problem with createdTime not being set ? because I tried your code on my machine and its updating the same row for a given customer id as @Deadpool already said. – Suraj Sep 17 '19 at 22:06
  • @Suraj no the creation time and updated time are updating..may be the equals method which is overriding is creating the problem? Not sure..any ideas? I forgot to mention in the post that i have a custom overrides equals method based in few attributes from customersEntity, but all the fields are same though.. – ging Sep 17 '19 at 23:27

1 Answers1

1

Add columnDefinition = "BINARY(16)" to customerid's @Column properties.

@Getter
@Setter
@Table(name = "Customers")
@Entity
public class CustomersEntity extends BasicEntity {
      @Id
     @GeneratedValue(generator = "UUID")
     @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
     @Column(name = "CustomerId", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
     private UUID customerid;

     //and some other fields
}

Without it customer_id column uses 256 bytes (in MySQL) and most probably this causes UUID equation to fail on subsequent saves of the same entity object which explains duplicates creation.

More information: Hibernate and UUID identifiers

MartinBG
  • 1,500
  • 13
  • 22
  • thanks for the response. I tried adding the change. But still i can see two rows being added. And we are using sql server not MySql. Sorry for not mentioning in the post. Any idea please? – ging Sep 18 '19 at 13:32
  • @ging Have you tried to drop and recreate the table (if that is an option for you)? – MartinBG Sep 18 '19 at 13:48
  • Yes. I did drop the table and created the table again. But no luck @MartinBG – ging Sep 18 '19 at 13:51
  • @ging I cannot recreate the problem on MySQL when customers_id column is set to binary(16). At that point I would try to simplify the setup as much as possible - test with a simple entity (no inheritance, just an id, default equals and hashCode methods), try with id of type Long, maybe do all of this in a new project to limit the noise. I have a simple project that I can upload to github if you want to test it there. – MartinBG Sep 18 '19 at 14:01
  • tried most of the things. tried with longId, with no inheritance and with default equals and hashcode every time by recreating the tables. But no luck but still i can see two rows being created :( Any other ideas or suggestions that you want me to try? Any other OnetoMany or ManyTo Many relationship might have an effect here? @MartinBG – ging Sep 18 '19 at 14:10
  • @ging Can you confirm that the type of customers_id column in the table when created with `columnDefinition = "BINARY(16)"` is `binary(16)` ? – MartinBG Sep 18 '19 at 14:19
  • @ging From what I have read in the following questions, this could be Hibernate+SQL Server issue: https://stackoverflow.com/questions/42559938/hibernate-uuid-with-postgresql-and-sql-server/48918942#48918942 https://stackoverflow.com/questions/41651681/different-representation-of-uuid-in-java-hibernate-and-sql-server – MartinBG Sep 18 '19 at 15:35