When building a contact form backend in a Spring Boot application, you typically need a database entity, a JPA repository, and a service layer to manage CRUD operations. In this post, we’ll walk through how to create a clean, layered backend for a simple Contact
entity using Spring Boot and JPA.
📦 Step 1: Define the Contact Entity
Let’s start by defining the Contact
class as a JPA entity:
java
import javax.persistence.*;
@Entity
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private String subject;
private String message;
// Getters and setters
}
📁 Step 2: Create a JPA Repository
Create an interface that extends JpaRepository
. This gives you CRUD methods out of the box.
java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ContactRepository extends JpaRepository<Contact, Long> {
}
⚙️ Step 3: Create a Service Interface
To maintain abstraction between your controller and the repository, define a service interface:
java
import java.util.List;
public interface ContactService {
Contact saveContact(Contact contact);
List<Contact> getAllContacts();
Contact getContactById(Long id);
Contact updateContact(Long id, Contact contact);
void deleteContact(Long id);
}
🔧 Step 4: Implement the Service
Now implement the service interface with actual business logic:
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ContactServiceImpl implements ContactService {
@Autowired
private ContactRepository contactRepository;
@Override
public Contact saveContact(Contact contact) {
return contactRepository.save(contact);
}
@Override
public List<Contact> getAllContacts() {
return contactRepository.findAll();
}
@Override
public Contact getContactById(Long id) {
return contactRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Contact not found with id: " + id));
}
@Override
public Contact updateContact(Long id, Contact contactDetails) {
Contact contact = getContactById(id);
contact.setName(contactDetails.getName());
contact.setEmail(contactDetails.getEmail());
contact.setSubject(contactDetails.getSubject());
contact.setMessage(contactDetails.getMessage());
return contactRepository.save(contact);
}
@Override
public void deleteContact(Long id) {
Contact contact = getContactById(id);
contactRepository.delete(contact);
}
}
🚨 Step 5: Add Custom Exception Handling (Optional)
To make your API more robust, define a custom exception for not found entities:
java
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
✅ Conclusion
With these five steps, you've created:
- A Contact entity representing your data model
- A JPA repository for database interaction
- A service layer for business logic and abstraction
- (Optional) A custom exception for clean error handling