请求协助:3张表的Hibernate Entity映射配置(1对多+1对一)
Got it, let's walk through how to map these three entities properly using JPA annotations. I'll assume you're using a standard JPA provider like Hibernate since it's the most common one.
First, let's recap the relationships to align on expectations:
emp(Employee) ↔empAddr(Employee Address): One-to-many — a single employee can have multiple address entries (e.g., home, work)empAddr↔addr(Address Details): One-to-one — each employee address entry links to exactly one full address record
Below are the annotated entity classes with proper mapping logic:
1. Employee Entity (Emp.java)
This is the parent entity for the 1:many relationship. We use @OneToMany pointing to the emp field in EmpAddr, and configure cascade rules based on typical business needs (adjust these if your use case requires different behavior).
import jakarta.persistence.*; import java.util.List; @Entity @Table(name = "emp") public class Emp { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "emp_id") private Long empId; // Core employee fields (customize these to match your table) private String fullName; private String email; private String department; // One-to-many relationship with EmpAddr @OneToMany(mappedBy = "emp", cascade = CascadeType.ALL, orphanRemoval = true) private List<EmpAddr> empAddrs; // Constructors, getters, setters public Emp() {} public Emp(String fullName, String email, String department) { this.fullName = fullName; this.email = email; this.department = department; } // Getters and setters for all fields (omitted for brevity, but include them in your code) }
2. Employee Address Entity (EmpAddr.java)
This acts as the join entity between Emp and Addr. It holds foreign keys for both relationships: @ManyToOne links back to the employee, and @OneToOne links to the address details.
import jakarta.persistence.*; @Entity @Table(name = "empAddr") public class EmpAddr { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "emp_addr_id") private Long empAddrId; // Foreign key to emp table (owning side of the 1:many relationship) @ManyToOne @JoinColumn(name = "emp_id", nullable = false) private Emp emp; // One-to-one relationship with Addr (owning side, holds the foreign key) @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "addr_id", nullable = false, unique = true) private Addr addr; // Optional: Label for the address type (home, work, temporary, etc.) private String addressType; // Constructors, getters, setters public EmpAddr() {} public EmpAddr(Emp emp, Addr addr, String addressType) { this.emp = emp; this.addr = addr; this.addressType = addressType; } // Getters and setters for all fields }
3. Address Details Entity (Addr.java)
This is the child entity for the 1:1 relationship. We can add a bidirectional link if needed, but it's optional — unidirectional mapping works fine if you don't need to navigate from Addr back to EmpAddr.
import jakarta.persistence.*; @Entity @Table(name = "addr") public class Addr { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "addr_id") private Long addrId; // Core address fields (match your table schema) private String street; private String city; private String state; private String zipCode; private String country; // Optional bidirectional 1:1 link (remove this if you only need unidirectional access) @OneToOne(mappedBy = "addr") private EmpAddr empAddr; // Constructors, getters, setters public Addr() {} public Addr(String street, String city, String state, String zipCode, String country) { this.street = street; this.city = city; this.state = state; this.zipCode = zipCode; this.country = country; } // Getters and setters for all fields }
Key Implementation Notes:
- Cascade Rules:
CascadeType.ALLmeans operations (save, update, delete) on the parent entity will propagate to child entities. Adjust this toCascadeType.PERSIST/CascadeType.MERGEif you don't want deletions to cascade. - Owning vs. Inverse Side: For the 1:many relationship,
EmpAddris the owning side (it holds theemp_idforeign key), somappedByis used onEmp. For the 1:1,EmpAddris the owning side (holdsaddr_id), soAddrusesmappedByfor bidirectional access. - Referential Integrity:
nullable = falseon@JoinColumnensures everyEmpAddris linked to an employee and address.unique = trueonaddr_idenforces the 1:1 constraint (one address can't be linked to multiple employee address entries). - Lazy Loading: By default,
@OneToManyuses lazy loading (great for performance). If you need related records loaded immediately, addfetch = FetchType.EAGER— but avoid this for large datasets.
If you need to adjust this for composite keys, non-standard ID generation strategies, or a specific JPA provider, just let me know!
内容的提问来源于stack exchange,提问作者CheckThisOut

