(This was done with MySQL, Hibernate and Lombok)
Setting: We have two Entities, Category
and Code
. Some categories must contain x codes, others cannot contain y codes and we want to leave open the possibility to “must contain z but not p” at the same time.
How: At database level we’ll have 4 tables with the following structure
client_category
FIELD_NAME | FIELD_TYPE | CONSTRAINTS |
---|---|---|
id | bigint(19) | PK (primary key) |
example_string | varchar(255) | |
example_bool | tinyint(1) |
client_code
FIELD_NAME | FIELD_TYPE | CONSTRAINTS |
---|---|---|
id | bigint(19) | PK |
value | varchar(255) |
client_category_contains_code
FIELD_NAME | FIELD_TYPE | CONSTRAINTS |
---|---|---|
id | bigint(19) | PK |
client_category_pk | bigint(19) | FK_client_category_contains_code |
client_code_pk | bigint(19) | FK_client_code_contains_code |
client_category_does_not_contain_code
FIELD_NAME | FIELD_TYPE | CONSTRAINTS |
---|---|---|
id | bigint(19) | PK |
client_category_pk | bigint(19) | FK_client_category_does_not_contain_code |
client_code_pk | bigint(19) | FK_client_code_does_not_contain_code |
The FKs (foreign keys) of the last two tables point to the PKs of client_category and client_code respectively. Important to be able to create this constraints is that they are the same type and have the same length.
This are the Java classes, representation of our Entities:
@Entity
@Getter
@Setter
@Table(name = "client_code")
public class ClientCode {
@Id
@GeneratedValue(strategy =
GenerationType.IDENTITY)
private Long id;
@Column(name = "value")
private String value;
}
@Entity
@Getter
@Setter
@Table(name = "client_category")
public class ClientCategory {
@Id
@GeneratedValue(strategy =
GenerationType.IDENTITY)
private Long id;
@Column(name = "example_string")
private String exampleString;
@Column(name = "example_bool")
private Boolean exampleBool;
@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name =
"client_category_contains_code",
joinColumns =
@JoinColumn(name = "client_category_pk",
referencedColumnName = "id"),
inverseJoinColumns =
@JoinColumn(name = "client_code_pk",
referencedColumnName = "id"))
private Set<ClientCode> containsCode;
@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name =
"client_category_does_not_contain_code",
joinColumns =
@JoinColumn(name = "client_category_pk",
referencedColumnName = "id"),
inverseJoinColumns =
@JoinColumn(name = "client_code_pk",
referencedColumnName = "id"))
private Set<ClientCode> doesNotContainCode;
}
The connection between tables at Java is built through javax annotations. This way, when we use our DAOs to retrieve a ClientCategory
, Hibernate will automatically retrieve all the ClientCode
and populate them into the appropiate Set<ClientCode>
.