Basic
- ํ
์ด๋ธ๋ช
์ ๋ช
์์ ์ผ๋ก ์ ์ธํ๋ ๊ฒ์ด ์ข๋ค. :
@Table(name = "COMPANY")
- EAGER ์ ๋ต์ ์ํ
@NamedEntityGraph
๋ Entity์ ์ ์ํด์ ์ฌ์ฌ์ฉํ์.
- ์คํ๋ผ์ธ ๋๊ด์ ์ ๊ธ์ด ํ์ํ๋ฉด
@Version
์ ์ฌ์ฉํ๋ค.
enum
์ ๊ฒฝ์ฐ String์ผ๋ก ํ๋ ์ฌ์ ๊ฐ ๋๋ฉด @Convert๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ซ๋ค.
- ๋ฑ๋ก ์์ ์ ๋ณด๋ ์์์ ์ด์ฉํ๊ธฐ ๋ณด๋ค๋ ๋ฑ๋ก & ์์ ๊ฐ๊ฐ์ฒด๋ฅผ ์ด์ฉํ๋ ๊ฒ์ด ๋ ๋์ ๊ฒ ๊ฐ๋ค.
- ๋๋ฉ์ธ ํํ๋ ฅ์ ๊ฐ์ง๋ ์ ์ ์์ฑ์ ๋ฉ์๋๊ฐ ์ข์ ๊ฒ ๊ฐ๋ค. ์์ฑ์๊ฐ ํ ๊ฐ ์ด์์ธ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
Lombok
@Data
๋ ์ฌ์ฉํ์ง ์๋๋ค.
- ๋ฌผ๋ก ํด๋์ค ๋ ๋ฒจ๋ก
@Setter
๋ ์ฌ์ฉํ์ง ์๋๋ค.
@Getter
๋ง ์ ์ธํ๊ณ ๋ณ๊ฒฝ์ด ํ์ํ ๊ฒฝ์ฐ์ ํด๋นํ๋ ๋ณ๊ฒฝ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.
@EqualsAndHashCode
์ฐ๊ด๊ด๊ณ ํ๋๋ ๋ฌด์กฐ๊ฑด exclude
์ ํฌํจ
@EqualsAndHashCode(exclude = {"partner", "ads"})
@ToString
์ฐ๊ด๊ด๊ณ ํ๋๋ ๋ฌด์กฐ๊ฑด exclude
์ ํฌํจ
@ToString(exclude = {"partner", "ads"})
- ๊ธฐ๋ณธ ์์ฑ์๋ ์กด์ฌ(JPA ์คํฉ)ํ๋ ๊ฐ๋ฅํ ๋
ธ์ถํ์ง ์๋๋ค
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Sample source
/**
* ์
์ฒด Entity
*/
@Entity
@Table(name = "COMPANY") // **ํ
์ด๋ธ๋ช
์ ๋ช
์์ ์ผ๋ก ์ ์ธํ๋ ๊ฒ์ด ์ข๋ค.**
@SequenceGenerator(name = "COMPANY_SEQ", sequenceName = "COMPANY_SEQ", allocationSize = 1) // sequence
@NamedEntityGraphs({ // **EAGER ์ ๋ต์ ์ํ NamedEntityGraph๋ Entity์ ์ ์ํด์ ์ฌ์ฌ์ฉํ์.**
@NamedEntityGraph(name = "Company.withPartnerAndAds", attributeNodes = {
@NamedAttributeNode("partner"),
@NamedAttributeNode("ads")
})
})
@Getter
@EqualsAndHashCode(exclude = {"partner", "ads"}) // **@EqualsAndHashCode ์ฐ๊ด๊ด๊ณ ํ๋๋ ๋ฌด์กฐ๊ฑด exclude์ ํฌํจ**
@ToString(exclude = {"partner", "ads"}) // **@ToString ์ฐ๊ด๊ด๊ณ ํ๋๋ ๋ฌด์กฐ๊ฑด exclude์ ํฌํจ**
@NoArgsConstructor(access = AccessLevel.PROTECTED) // **๊ธฐ๋ณธ ์์ฑ์๋ ์กด์ฌํ๋ ๊ฐ๋ฅํ ๋
ธ์ถํ์ง ์๋๋ค.**
@Slf4j
public class Company implements Serializable {
// **์ง๋ ฌํ ๋ง์ปค ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ serialVersionUID ๊ผญ ์ ์ธํ๋ค.**
private static final long serialVersionUID = 2415772833217876197L;
/**
* ์
์ฒด ๋ฒํธ (PK)
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "COMPANY_SEQ")
@Column(name = "COMPANY_NO")
private Long companyNo;
/**
* ๋ฒ์ for LOCK **ํ์ํ๋ฉด Version ์์ฑ์ ์ฌ์ฉํ๋ค**
*/
@Version
@Column(name = "version", nullable = false)
private long version;
/**
* ๋ด๋น ํ๋ ฅ์ฌ (fk)
*/
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "PARTNER_NO", nullable = false, foreignKey = @ForeignKey(name = "FK_COMPANY_PARTNER_NO"))
private Partner partner;
/**
* ์
์ฒด์ ๋ฑ๋ก๋ ๊ด๊ณ ๋ค (fk)
*/
@OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
private Set<Ad> ads;
/**
* ์นดํ
๊ณ ๋ฆฌ
*/
@Enumerated(EnumType.STRING) // **String์ผ๋ก ํ๋ ์ฌ์ ๊ฐ ๋๋ฉด @Convert๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ซ๋ค.**
@Column(name = "CATEGORY", length = 50, nullable = false)
private CompanyCategory category;
/**
* ์
์ฒด๋ช
*/
@Column(name = "COMPANY_NAME", length = 100, nullable = false)
private String companyName;
/**
* ์ ํ๋ฒํธ
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "phone", column = @Column(name = "PHONE", length = 20, nullable = false))
})
private Phone phone;
/**
* ์ฃผ์
*/
@AttributeOverrides({
@AttributeOverride(name = "zipCode", column = @Column(name = "ZIP_CODE", length = 5)),
@AttributeOverride(name = "address", column = @Column(name = "ADDRESS", length = 200, nullable = false)),
@AttributeOverride(name = "detailAddress", column = @Column(name = "DETAIL_ADDRESS", length = 200))
})
private Address address;
/**
* ์์
์์ ์๊ฐ
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "hour", column = @Column(name = "SALES_START_TIME_HOUR", length = 2, nullable = false)),
@AttributeOverride(name = "minute", column = @Column(name = "SALES_START_TIME_MINUTE", length = 2, nullable = false)),
})
private Time salesStartTime;
/**
* ์์
๋ง๊ฐ ์๊ฐ
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "hour", column = @Column(name = "SALES_END_TIME_HOUR", length = 2, nullable = false)),
@AttributeOverride(name = "minute", column = @Column(name = "SALES_END_TIME_MINUTE", length = 2, nullable = false)),
})
private Time salesEndTime;
/**
* ์ต์์ฃผ๋ฌธ๊ธ์ก
*/
@Column(name = "MINIMUM_ORDER_AMOUNT", nullable = false)
private long minimumOrderAmount; // **์ซ์ํ NOT NULL ํ์
์ด๋ฉด์ ์ฐ์ฐ์ด ์๊ตฌ๋๋ฉด primitive type์ผ๋ก ์ ์ธํ๋ ๊ฒ์ด ์ข๋ค.**
/**
* ๊ณ์ฝ์ ์ด๋ฏธ์ง
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "originName", column = @Column(name = "CONTRACT_IMAGE_ORIGIN", nullable = false)),
@AttributeOverride(name = "storageName", column = @Column(name = "CONTRACT_IMAGE_STORAGE", nullable = false))})
/**
* ๋ฉ๋ด1 ์ด๋ฏธ์ง
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "originName", column = @Column(name = "MENU1_IMAGE_ORIGIN")),
@AttributeOverride(name = "storageName", column = @Column(name = "MENU1_IMAGE_STORAGE"))})
private SaveFile menu1Image;
/**
* ์ฐจ๋จ์ฌ๋ถ
*/
@ColumnDefault("'N'") // **hibernate์ @ColumnDefault๋ ๊ฐ๋
์ฑ ํฅ์์ ๋์**
@Column(name = "BLOCK_YN", length = 1, nullable = false, insertable = false)
@Convert(converter = YnAttributeConverter.class)
private boolean block;
/**
* ๋ฑ๋ก & ์์ Value
*/
@Embedded
private CreateAndUpdate cau;
/**
* ๋ฑ๋ก์ ์ํ ์ ์ ์์ฑ์ **๊ผญ ํ์ํ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ๋ ์์ฑ์๋ฅผ ์ ๊ณตํ๋ค. ๋๋ฉ์ธ ํํ๋ ฅ์ ์ํด์ ์ ์ ์์ฑ์๋ฅผ ์ถ์ฒํ๋ค.**
*/
public static Company create(@NonNull Partner partner,
@NonNull CompanyCategory category,
@NonNull String companyName,
@NonNull Phone phone,
@NonNull Address address,
@NonNull Time salesStartTime,
@NonNull Time salesEndTime,
@NonNull Long minimumOrderAmount,
@NonNull SaveFile contractImage,
Business business,
SaveFile menu1Image,
@NonNull Long createMemberNo) {
// ...
result.cau = CreateAndUpdate.create(createMemberNo);
return result;
}
// ๋ฑ๋ก ์ ์ ํจ์ฑ ์ฒดํฌ
@PrePersist
protected void onPrePersist() {
cau.checkPreInsert();
}
// ์์ ์ ์ ํจ์ฑ ์ฒดํฌ
@PreUpdate
protected void onPreUpdate() {
cau.checkPreUpdate();
}
/**
* ๋ฐฐ๋ฌ์
์ฒด ์์ **๋ชจ๋ ํญ๋ชฉ์ ๋ํ setter๋ฅผ ์ ๊ณตํ์ง ์๊ณ ๋ณ๊ฒฝ์ ํ๋ ๋๋ฉ์ธ ํํ๋ ฅ์ ๊ฐ์ง๋ ๋ณ๊ฒฝ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.**
*
* @param update ์์ ํ๋ผ๋ฏธํฐ
*/
public void update(CompanyUpdate update) {
if (companyNo == null) {
throw new IllegalStateException("'companyNo' must not be null");
}
// Check version for optimistic lock
if (version != update.getVersion()) {
throw new OptimisticLockException("Conflict version");
}
this.version = update.getVersion();
this.partner = update.getPartner();
this.category = update.getCategory();
this.companyName = update.getCompanyName();
// ๊ด๋ฆฌ์์ธ ๊ฒฝ์ฐ์๋ง ์ ํ๋ฒํธ๋ฅผ ์์ ํ ์ ์์
if (update.getUser().isAdmin()) {
this.phone = update.getPhone();
}
// ...
if (update.getMenu1Image() != null) {
this.menu1Image = update.getMenu1Image();
}
this.cau.update(update.getUser().getUserNo());
}
/**
* ๊ด๋ฆฌ ํ๋ ฅ์ฌ ๋ณ๊ฒฝ
*
* @param newPartner ๋ณ๊ฒฝํ ํ๋ ฅ์ฌ
*/
public void changePartner(Partner newPartner, Long updateUserNo) {
if (this.partner == newPartner) {
return;
}
this.partner = newPartner;
this.cau.update(updateUserNo);
}
public boolean hasContractImage() {
return contractImage != null && contractImage.isValid();
}
public boolean hasBusinessImage() {
return business != null && business.getImage() != null && business.getImage().isValid();
}
public boolean hasMenu1Image() {
return menu1Image != null && menu1Image.isValid();
}
public boolean hasMenu2Image() {
return menu2Image != null && menu2Image.isValid();
}
public void block(Partner user) {
if (cau == null) {
throw new IllegalStateException("cau must not be null");
}
cau.update(user.getUserNo());
block = true;
}
public boolean hasPerfectBusiness() {
return business != null && business.isPerfect();
}
/**
* ์๋ฒฝํ ์ฌ์
์ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋์ง ์ฒดํฌ
* @throws IllegalStateException ์ฌ์
์ ์ ๋ณด๊ฐ ์๋ฒฝํ์ง ์์ผ๋ฉด ๋ฐ์
*/
public void checkPerfectBusiness() {
if (!hasPerfectBusiness()) {
throw new IllegalStateException("Company is invalid : " + companyNo);
}
}
/**
* ๊ด๊ณ ์ค์ธ ๊ด๊ณ ๊ฐ ์กด์ฌํ๋๊ฐ?
*/
public boolean hasOpenAd() {
for (Ad ad : ads) {
if (ad.getAdDisplayStatus() == AdDisplayStatus.OPEN) {
return true;
}
}
return false;
}
}