Home Spring Boot Spring Data JDBC - Embedded entities examples

Spring Data JDBC – Embedded entities examples

In this tutorial we will see examples on Embedded entities in Spring Data JDBC using @Embedded for simple types, Collections like List, Set and Map.

1. Embedding Entities

1.1. Used Technologies :

  1. Spring Boot 2.3.0.RELEASE
  2. Spring Data JDBC 2.0.0.RELEASE
  3. Spring Framework 5.2.6.RELEASE
  4. H2 / MySql DB
  5. Lombok 1.18.12
  6. JUnit 5

@Embedded supports Since Spring Data JDBC 1.1. Embedded entities are used to have value objects in your java data model, even if there is only one table in your database. Following Image illustrates the Embedded entity mapping.

1.2. Test the mapping :

Following is the JUnit 5 test case for testing Embedded entity mapping using Spring Data JDBC.

@SpringBootTest
public class EmbeddedMappingTest {

	@Autowired
	private CollegeRepository collegeRepository;

	@Autowired
	private UserTestRepository userTestRepository;

	@Test
	@DisplayName("Basic Embedded Mapping")
	@Sql(scripts = "/embeded_basic_mapping.sql")
	void embeddedMappingTest() {
		College college = new College();
		college.setCollegeName("Vivekananda PG College");
		// Setting Composite Value Type
		ContactAddress address = new ContactAddress();
		address.setStreetAddress("Clock Tower, Mahbub College Campus");
		address.setCity("Secunderabad");
		address.setState("Andhrapradesh");
		address.setAreaCode("500003");
		college.setAddress(address);

		College createdCollege = collegeRepository.save(college);
		System.err.println(createdCollege);
		Assert.assertTrue(createdCollege != null);

		User user = new User();
		user.setUserName("mike");
		user.setPassword("password");
		user.setCreatedTime(new Date());
		user.setUserType(UserType.EMPLOYEE);
		user.setAddress(address);

		User createdUser = userTestRepository.save(user);
		System.err.println(createdUser);
		Assert.assertTrue(createdUser != null);
	}
}

2. Embedded Collections – List and Set

Let’s say that we have to persist multiple Contact Addresses and multiple Contact Numbers for one users, in such case data base tables structure might be look like following.

CREATE TABLE `USER` (
  `ID` INT NOT NULL AUTO_INCREMENT,
  `USER_NAME` VARCHAR(45) NOT NULL,
  `PASSWORD` VARCHAR(45) NOT NULL,
  `CREATED_TIME` DATETIME NOT NULL,
  `UPDATED_TIME` DATETIME NULL,
  `USER_TYPE` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE INDEX `USER_NAME_UNIQUE` (`USER_NAME` ASC)
 );
  
CREATE TABLE `Contacts` (
  `ID` INT NOT NULL,  /* user id */
  `CONTACT_NO` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`ID`, `CONTACT_NO`)
 );
    
CREATE TABLE `Contact_Address` (
  `STREET` VARCHAR(45) NOT NULL,
  `STATE` VARCHAR(45) NOT NULL,
  `CITY` VARCHAR(45) NOT NULL,
  `ZIP_CODE` VARCHAR(45) NOT NULL,
  `USER_ID` INT NOT NULL,
  `ADDR_TYPE` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`USER_ID`, `ADDR_TYPE`)
 );

For the above tables design, to persist collection of contact addresses and contact numbers for one user, we have to map embedded entities using @MappedCollection.

2.1. ContactAddress entity mapping :

@Data
public class ContactAddress {
    
    private String street;
    private String state;
    private String city;
    @Column("ZIP_CODE")
    private String areaCode;
    @Column("ADDR_TYPE")
    private AddressType addressType;
}

2.2. Contacts table mapping :

@Table("CONTACTS")
@Data @AllArgsConstructor
public class Contact {

	private String contactNo;
}

2.3. User Entity Mapping :

@Data
public class User {

	@Id
	private Long id;

	private String userName;
	private String password;
	private Date createdTime;
	private Date updatedTime;

	@MappedCollection(idColumn = "USER_ID")
	private Set<ContactAddress> address;

	@MappedCollection(idColumn = "ID", keyColumn = "CONTACT_NO")
	private List<Contact> contacts;

	private UserType userType;

}

2.4. Testing Embedded Collection mapping :

@SpringBootTest
public class EmbeddedCollectionMappingTest {

	@Autowired
	private UserEembeddableCollectionTestRepository userTestRepository;

	@Test
	@DisplayName("Embedded Collection Mapping Test")
	@Sql(scripts = "/embeded_collection_mapping.sql")
	void embeddedMappingTest() {

		User user = new User();
		user.setUserName("mike");
		user.setPassword("password");
		user.setCreatedTime(new Date());
		user.setUserType(UserType.EMPLOYEE);
		user.setAddress(getAddressList());

		// Creating contacts List
		List<Contact> contactList = new ArrayList<>();
		contactList.add(new Contact("(817) 569-8221"));
		contactList.add(new Contact("(817) 569-8281"));
		// Setting contacts to User
		user.setContacts(contactList);

		User createdUser = userTestRepository.save(user);
		System.err.println(createdUser);
		Assert.assertTrue(createdUser != null);
	}

	public Set<ContactAddress> getAddressList() {

		Set<ContactAddress> adresses = new HashSet<ContactAddress>();

		// Setting Contact Address1
		ContactAddress address = new ContactAddress();
		address.setStreet("Clock Tower, Mahbub College Campus");
		address.setCity("Secunderabad");
		address.setState("Andhrapradesh");
		address.setAreaCode("500003");
		address.setAddressType(AddressType.PERMANENT);

		// Setting Contact Address2
		ContactAddress currentAddress = new ContactAddress();
		currentAddress.setStreet("FN 501, Vamseekuteer");
		currentAddress.setCity("Secunderabad");
		currentAddress.setState("Andhrapradesh");
		currentAddress.setAreaCode("500003");
		currentAddress.setAddressType(AddressType.RESIDENCE);

		adresses.add(address);
		adresses.add(currentAddress);

		return adresses;
	}

}

3. Mapping Embedded Entities using java.util.Map

In the above example, if Contacts table have an additional column ‘CONTACT_TYPE’ , we can choose Map in such case to map that additional column in entity mapping.

3.1. Contacts table :

CREATE TABLE `Contacts` (
  `ID` INT NOT NULL,
  `CONTACT_NO` VARCHAR(45) NOT NULL,
  `CONTACT_TYPE` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`ID`, `CONTACT_NO`, `CONTACT_TYPE`)
);

3.2. Contacts Entity mapping :

@Table("CONTACTS")
@Data @AllArgsConstructor
public class Contact {

	private String contactNo;
}

3.3. User entity mapping :

@Data
public class User {

	@Id
	private Long id;

	private String userName;
	private String password;
	private Date createdTime;
	private Date updatedTime;

	@MappedCollection(idColumn = "ID", keyColumn = "CONTACT_TYPE")
	private Map<ContactType, Contact> contacts;

	private UserType userType;

}

3.4. Testing the persisting Map :

@SpringBootTest
public class PersistingMapTest {

	@Autowired
	private UserCollectionMapTestRepository userTestRepository;

	@Test
	@DisplayName("Persisting Map Test")
	@Sql(scripts = "/persist_map.sql")
	void embeddedMappingTest() {

		User user = new User();
		user.setUserName("mike");
		user.setPassword("password");
		user.setCreatedTime(new Date());
		user.setUserType(UserType.EMPLOYEE);

		Map<ContactType, Contact> contactsMap = new HashMap();
		contactsMap.put(ContactType.OFFICE, new Contact("(817) 569-8221"));
		contactsMap.put(ContactType.MOBILE, new Contact("(817) 569-8281"));
		user.setContacts(contactsMap);

		User createdUser = userTestRepository.save(user);
		System.err.println(createdUser);
		Assert.assertTrue(createdUser != null);
	}
}

4. Conclusion

In this tutorial we have seen examples on Embedded entities in Spring Data JDBC using @Embedded for simple types, Collections like List, Set and Map.

5. References

  1. Spring Documentation
  2. Jpa Embedded Types mapping
  3. JPA Embedded Collection
  4. Spring Boot Data JDBC Example
  5. Spring Boot H2 Example

Satish Varma
Satish Varmahttps://javabydeveloper.com
Satish is post graduated in master of computer applications and experienced software engineer with focus on Spring, JPA, REST, TDD and web development. Follow him on LinkedIn or Twitter or Facebook

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Stay in Touch

Categories