I have a scenario where I have the user table and the address table. The address table is a value objects in domain driven design in my understanding. How do I store value objects in mysql database? this sounds a bit confusing but I couldn't understand this idea value objects are immutable but how to store them?
Below are classes of my two entity
user.java
@Getter @Setter @NoArgsConstructor
@Entity // This tells Hibernate to make a table out of this class
@Table(name="user")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@JsonProperty("userid")
@Column(name="userid")
private Long user_id;
@JsonProperty("user_nome")
private String nome;
@JsonProperty("user_email")
@Column(unique = true, nullable = false)
private String email;
@JsonProperty("user_cpf")
private String cpf;
@JsonProperty("user_telefone")
private String telefone;
@JsonProperty("user_celular")
private String celular;
@JsonProperty("user_senha")
private String senha;
@Column(name="createdAt", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
@JsonProperty("user_createdAt")
private Date createdAt;
@Column(name="updateAt", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
@JsonProperty("user_updateAt")
private Date updateAt;
/*Person p1 = new Person("Tom", "Smith");
p1.setId(1L);
p1.setStartDate(new Date(System.currentTimeMillis())); */
}
class Address:
@Getter @Setter @NoArgsConstructor
@Entity // This tells Hibernate to make a table out of this class
@Table(name="address")
public class Address {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@JsonProperty("address_id")
private Long address_id;
@JsonProperty("address_endereco")
private String endereco;
@JsonProperty("address_bairro")
private String bairro;
@JsonProperty("address_numero")
private String numero;
@JsonProperty("address_complemento")
private String complemento;
@JsonProperty("address_cidade")
private String cidade;
@OneToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "userid")
private User userid;
}
CodePudding user response:
Basically however you want: you could enforce immutability in the database, but you don't have to. Immutability can be enforced in the database by creating an unique constraint on a combination of values of an address, zipcode house number for example.
As a database administrator I personally don't like developers enforcing immutability in the database because I see implementing/enforcing business logic in the database as a category error. What is an immutable value within the domain, to me is just data that needs to be consistently stored. Database rules are meant to ensure data consistency and the added complexity of implementing immutability in the database can interfere with that. Lets do a thought experiment:
You ensure that an address value is unique in the database with a constraint that covers all properties and store your data. Some time later a customer places an order that happens to have the same address, but he lives on the North Pole. The order is saved but the address isn't because my server throws an error because the address violates the constraint because it already exsists in the US, but that's not saved/part of the constraint. Now I have a problem because that orphaned order violates the data model, you complain to me because my server threw an error and now it's up to me to figure out what's wrong with your design decision to apply the abstract concept of immutability outside your domain, and have to update the data definition in a production environment in order to fix it.
So I think it's best you acknowledge that by storing data it leaves your domain and that is a risk your design should take into account. What I'd advice (or silently implement haha) would be the addition of an ID within the table and a record versions of the same 'immutable value' for tracability, consistency and agility to react to unforseen circumstances. Just like with user and transaction entities ;)