I have a multi tenants LMS application. I have Academy
entity which will act as tenant in my LMS. Every other entity will have academy_id
column.
Using discriminator based multi tenancy feature of hibernate.
@Entity
@Data
public class Academy implements Serializable {
@Id private long id;
@Column(nullable = false)
private String name;
@Column(nullable = false, unique = true)
private String domain;
@Column(nullable = false)
private boolean isActive;
@Column(nullable = false)
private long features;
@Column(nullable = false, updatable = false)
private ZonedDateTime createdAt;
@Column(nullable = false)
@Version
private ZonedDateTime lastModified;
@PrePersist
protected void setCreatedAt() {
createdAt = ZonedDateTime.now();
}
}
I have another entity, AcademyUser
.
@Entity
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"academy_id", "email"})})
public class AcademyUser extends EntityBase {
@EmbeddedId private AcademyUserKey key;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private UserType userType;
private PhoneNumber phoneNumber;
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String lastName;
@Column(nullable = false)
private boolean isBlocked;
@Column(nullable = false)
private short roles;
}
// AcademyUserKey.java
@Data
@Builder
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
public class AcademyUserKey implements Serializable {
@TenantId
@Column(name = "academy_id") // Map to your database column
private long academyId;
@Column(name = "user_email")
private String email;
}
I am getting the following error
Failed to initialize JPA EntityManagerFactory: Property 'org.w3worker.academy.api_server.academy_user.models.AcademyUser.key.academy' is annotated 'interface org.hibernate.annotations.TenantId' which is not an '@IdGeneratorType'
In sort, unable to use @TenantId
as part of the primary key. Is there any solution?
Do NOT map relationships inside @Embeddable
classes. (Only primitive types are allowed there.)
To use tenantId as a part of the primary key, update the code as below.
@Data
@Builder
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
public class AcademyUserKey implements Serializable {
@Column(name = "academy_id")
private long academyId;
@Column(name = "user_email")
private String email;
}
@Entity
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"academy_id", "email"})})
public class AcademyUser extends EntityBase {
@EmbeddedId
private AcademyUserKey key;
@ManyToOne
@MapsId("academyId")
@JoinColumn(name = "academy_id")
private Academy academy;
...
}