In a relational database in a one-to-one relationship, a row in table X can have no more than one matching row in table Y, and vice versa. X one-to-one relationship is created if both of the related columns are primary keys or have unique constraints.
In Object oriented programming, one instance of entity exactly refers to one instance of another entity in the relation called one-to-one relation.
Tables structure in Database :
User Entity Mapping :
Technologies Used in following example :
- JPA 2.1
- Hibernate 5.2.6
- MySql 8.0
- Maven 3
- Spring Tool Suite (STS) 3.9.8
- Java 1.8
@Entity(name="USER") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "native") @GenericGenerator(name = "native", strategy = "native") @Column(name = "ID") private Long id; @Temporal(value=TemporalType.TIMESTAMP) @Column(name="CREATED_TIME") private Date creationTime; @Temporal(value=TemporalType.TIMESTAMP) @Column(name="UPDATED_TIME") private Date updatedTime; @Temporal(value=TemporalType.DATE) @Column(name="DOB") private Date dateofBirth; @Enumerated(value=EnumType.STRING) @Column(name="USER_TYPE") private UserType userType; @Column(name = "FIRST_NAME") private String firstName; @Column(name = "LAST_NAME") private String lastName; //Getters and Setters
Credentials Entity Mapping :
@Entity(name="USER_CREDENTIALS") public class Credentials { @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "native") @GenericGenerator(name = "native", strategy = "native") @Column(name = "CREDS_ID") private Long credentialId; @Column(name = "USERNAME") private String userName; @Column(name = "PASSWORD") private String password; @OneToOne(cascade=CascadeType.ALL)//one-to-one @JoinColumn(name="USER_ID") private User user; //non owning entity //Getters and Setters
Cascade :
- Whenever rows in the parent table manipulated (inserted, updated, deleted) the respective rows of the child table with a matching key column will be manipulated as well. This is called Cascade in Database.
- JPA translates entity state transitions to database DML statements.
@JoinColumn :
- @JoinColumn Specifies a column for joining an entity association or element collection. The annotation
@OneToOne
indicates that this entity is the owner of the relationship. That is the corresponding table has a column with a foreign key to the referenced table.
To Understand Cascade and @JoinColumn mapping in entity associations see :
Key points to understand associations
Testing one-to-one mapping :
/** * JPA One-To-One Unidirectional * */ public class App { public static void main( String[] args ) { EntityManagerFactory emf = null; EntityManager entityManager = null; EntityTransaction transaction = null; try{ emf = Persistence.createEntityManagerFactory("jbd-pu"); entityManager = emf.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); User user = new User(); user.setFirstName("Peter"); user.setLastName("Milanovich"); user.setCreationTime(new Date()); user.setDateofBirth(new Date()); user.setUserType(UserType.EMPLOYEE); Credentials credentials = new Credentials(); credentials.setUserName("peterm"); credentials.setPassword("password"); credentials.setUser(user); //Credentials object having all the information (User and Credentials) entityManager.persist(credentials); transaction.commit(); }catch(Exception e){ transaction.rollback(); e.printStackTrace(); }finally{ entityManager.close(); emf.close(); } } }
Output :
INFO - HHH000400: Using dialect: org.hibernate.dialect.MySQLInnoDBDialect INFO - HHH000397: Using ASTQueryTranslatorFactory Hibernate: insert into USER (CREATED_TIME, DOB, FIRST_NAME, LAST_NAME, UPDATED_TIME, USER_TYPE) values (?, ?, ?, ?, ?, ?) Hibernate: insert into USER_CREDENTIALS (PASSWORD, USER_ID, USERNAME) values (?, ?, ?) INFO - HHH000030: Cleaning up connection pool [jdbc:mysql://localhost:3306/jpa_JBD]
Download Application – JPA-OneToOne-UniDirection.zip (14 KB)