Reputation: 2097
I am having an issue where hibernate is storing the same keys multiple times. Example, lets say I have an object with the primary key as "stack overflow". I create another object with the same primary key "stack overflow", hibernate will save both objects and each object will have its own record. I personally believe this is caused by the uuid as "stack overflow" wouldn't appear in the database twice but the unique uuid of each object is different. How do I fix generating a different uuid for strings?
Users class, the email field works as expected and doesn't allow duplicate emails.
@Entity
@Table(name = "Users")
public class User {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String username;
@Column(unique = true)
private String email;
private String password;
private String firstName;
private String lastName;
// Getters and Setters
Table Data
+--------------------------------------+-------------------------+-----------+----------+----------+
| username | email | firstName | lastName | password |
+--------------------------------------+-------------------------+-----------+----------+----------+
| 2afcb68b-e7e2-4b7d-bb8e-c886b34092aa | [email protected] | charlie | sexton | sexton |
| 365a64b0-e036-4654-ad3a-afe2440f5b37 | [email protected] | charlie | sexton | sexton |
| 9f9c89f5-7fba-4600-bb86-951c64d9988e | [email protected] | charlie | sexton | sexton |
| a27c5ab7-c651-4027-8a89-0eb516930b31 | [email protected] | charlie | sexton | sexton |
| f7252552-f54b-453a-9806-2d2e4fd40f43 | [email protected] | charlie | sexton | sexton |
+--------------------------------------+-------------------------+-----------+----------+----------+
Code used to create the data....So the first three entries in the database are correct. So what I did was run the below code once to generate the first three records. Then to get the last two records I deleted session.save(user); and then changed the email address of user2 and user3 on the second run. I didn't touch the username field at all of user2 or user3 on the second run, why did hibernate allow this? I am relatively new to hibernate and couldn't find and resources. The Google God wasn't nice to me.
User user = new User();
user.setUsername("charles");
user.setPassword("sexton");
user.setFirstName("charlie");
user.setLastName("sexton");
user.setEmail("[email protected]");
User user2 = new User();
user2.setUsername("cs");
user2.setPassword("sexton");
user2.setFirstName("charlie");
user2.setLastName("sexton");
user2.setEmail("[email protected]");
User user3 = new User();
user3.setUsername("cs");
user3.setPassword("sexton");
user3.setFirstName("charlie");
user3.setLastName("sexton");
user3.setEmail("[email protected]");
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.save(user2);
session.save(user3);
List<Expense> listReport = query.list();
session.getTransaction().commit();
session.close();
Upvotes: 0
Views: 832
Reputation: 1486
I think this is because you generate UUID's, instead of making a UUID from your username
I tested this with my code:
package nl.testing.startingpoint;
import java.io.IOException;
import java.util.UUID;
public class Main {
public static void main(String args[]) throws IOException{
String a = "stack Overflow";
String b = "stack Overflow";
System.out.println(UUID.nameUUIDFromBytes(a.getBytes()).toString());
System.out.println(UUID.nameUUIDFromBytes(b.getBytes()).toString());
System.out.println(UUID.nameUUIDFromBytes(a.getBytes()).toString());
System.out.println(UUID.nameUUIDFromBytes(b.getBytes()).toString());
}
}
and this is the result:
e6b8789f-8fac-3c40-94ae-6f2fe4b009fc
e6b8789f-8fac-3c40-94ae-6f2fe4b009fc
e6b8789f-8fac-3c40-94ae-6f2fe4b009fc
e6b8789f-8fac-3c40-94ae-6f2fe4b009fc
But because you use annotations with
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
The String username is overwritten with the generated UUID from hibernate. Instead, i think you should create a UUID from the string you are passing into the constructor.
NOTE: I did not test the latter, it's an assumption!
Upvotes: 1