2
\$\begingroup\$

I have a class Currency, where I want to store business logic for working with currencies:

public class Currency implements Comparable<Currency> {
 public static final int NAME_MAX_STRING_LENGTH = 50;
 public static final int ISO_CODE_STRING_LENGTH = 3;
 public static final int SYMBOL_STRING_LENGTH = 1;
 public static final int COMMENTS_MAX_STRING_LENGTH = 100;
 private String name;
 private String isoCode;
 private String symbol;
 private String comments;
 public Currency(String name, String isoCode, String symbol, String comments) {
 setName(name);
 setIsoCode(isoCode);
 setSymbol(symbol);
 setComments(comments);
 }
 public String getIsoCode() {
 return isoCode;
 }
 public String getName() {
 return name;
 }
 public String getSymbol() {
 return symbol;
 }
 public String getComments() {
 return comments;
 }
 public void setIsoCode(String isoCode) {
 if (isoCode == null) {
 throw new ArgumentIsNullException("isoCode");
 }
 if (isoCode.length() != ISO_CODE_STRING_LENGTH) {
 throw new IllegalArgumentException(
 "ISO code should be consisted of 3 letters.");
 }
 if (!isoCode.matches(defineRegularExpressionForIsoCode())) {
 throw new IllegalArgumentException("ISO code is not valid.");
 }
 this.isoCode = isoCode;
 }
 public void setName(String name) {
 if (name == null) {
 throw new ArgumentIsNullException("name");
 }
 if (name.length() > NAME_MAX_STRING_LENGTH) {
 StringBuilder exceptionMessageBuilder = new StringBuilder();
 exceptionMessageBuilder
 .append("Length of name's string can not be more than ");
 exceptionMessageBuilder.append(NAME_MAX_STRING_LENGTH);
 exceptionMessageBuilder.append(" symbols.");
 throw new IllegalArgumentException(
 exceptionMessageBuilder.toString());
 }
 this.name = name;
 }
 public void setSymbol(String symbol) {
 if (symbol == null) {
 throw new ArgumentIsNullException("symbol");
 }
 if (symbol.length() != SYMBOL_STRING_LENGTH) {
 throw new IllegalArgumentException(
 "Currency's symbol should be exactly one character.");
 }
 this.symbol = symbol;
 }
 public void setComments(String comments) {
 if (comments != null && comments.length() > COMMENTS_MAX_STRING_LENGTH) {
 StringBuilder exceptionMessageBuilder = new StringBuilder();
 exceptionMessageBuilder
 .append("Length of comments' string can not be more than ");
 exceptionMessageBuilder.append(COMMENTS_MAX_STRING_LENGTH);
 exceptionMessageBuilder.append(" symbols.");
 throw new IllegalArgumentException(
 exceptionMessageBuilder.toString());
 }
 this.comments = comments;
 }
 private String defineRegularExpressionForIsoCode() {
 return "^[A-Z][A-Z][A-Z]$";
 }
 @Override
 public int compareTo(Currency currency) {
 return this.getIsoCode().compareTo(currency.getIsoCode());
 }
 @Override
 public int hashCode() {
 final int prime = 31;
 int result = 1;
 result =
 prime * result + ((comments == null) ? 0 : comments.hashCode());
 result = prime * result + ((isoCode == null) ? 0 : isoCode.hashCode());
 result = prime * result + ((name == null) ? 0 : name.hashCode());
 result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
 return result;
 }
 @Override
 public boolean equals(Object obj) {
 if (this == obj)
 return true;
 if (obj == null)
 return false;
 if (getClass() != obj.getClass())
 return false;
 Currency other = (Currency) obj;
 if (comments == null) {
 if (other.comments != null)
 return false;
 } else if (!comments.equals(other.comments))
 return false;
 if (isoCode == null) {
 if (other.isoCode != null)
 return false;
 } else if (!isoCode.equals(other.isoCode))
 return false;
 if (name == null) {
 if (other.name != null)
 return false;
 } else if (!name.equals(other.name))
 return false;
 if (symbol == null) {
 if (other.symbol != null)
 return false;
 } else if (!symbol.equals(other.symbol))
 return false;
 return true;
 }
}

CurrencyEntity interface:

public interface CurrencyEntity {
 void setName(String name);
 String getName();
 void setIsoCode(String isoCode);
 String getIsoCode();
 void setSymbol(String symbol);
 String getSymbol();
 void setComments(String comments);
 String getComments();
}

which CurrencyEntityAtJpa implements for working with Hibernate:

@Entity
@Table(name = "currencies")
public class CurrencyEntityAtJpa implements CurrencyEntity {
 public static final int NAME_MAX_STRING_LENGTH =
 Currency.NAME_MAX_STRING_LENGTH;
 public static final int ISO_CODE_STRING_LENGTH =
 Currency.ISO_CODE_STRING_LENGTH;
 public static final int SYMBOL_STRING_LENGTH =
 Currency.SYMBOL_STRING_LENGTH;
 public static final int COMMENTS_MAX_STRING_LENGTH =
 Currency.COMMENTS_MAX_STRING_LENGTH;
 private Currency currency;
 private long id;
 public CurrencyEntityAtJpa() {
 setCurrency(new Currency("Invalid currency", "INV", "I", null));
 }
 public CurrencyEntityAtJpa(String name, String isoCode, String symbol,
 String comments) {
 setCurrency(new Currency(name, isoCode, symbol, comments));
 }
 public CurrencyEntityAtJpa(Currency currency) {
 this(currency.getName(), currency.getIsoCode(), currency.getSymbol(),
 currency.getComments());
 }
 @Transient
 public Currency getCurrency() {
 return currency;
 }
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column
 public long getId() {
 return id;
 }
 @Override
 @Column(name = "iso_code", nullable = false, length = ISO_CODE_STRING_LENGTH)
 public String getIsoCode() {
 return getCurrency().getIsoCode();
 }
 @Override
 @Column(name = "name", nullable = false, length = NAME_MAX_STRING_LENGTH)
 public String getName() {
 return getCurrency().getName();
 }
 @Override
 @Column(name = "symbol", nullable = false, length = SYMBOL_STRING_LENGTH)
 public String getSymbol() {
 return getCurrency().getSymbol();
 }
 @Override
 @Column(name = "comments", nullable = true, length = COMMENTS_MAX_STRING_LENGTH)
 public String getComments() {
 return getCurrency().getComments();
 }
 private void setCurrency(Currency currency) {
 this.currency = currency;
 }
 public void setId(long id) {
 this.id = id;
 }
 @Override
 public void setIsoCode(String isoCode) {
 getCurrency().setIsoCode(isoCode);
 }
 @Override
 public void setName(String name) {
 getCurrency().setName(name);
 }
 @Override
 public void setSymbol(String symbol) {
 getCurrency().setSymbol(symbol);
 }
 @Override
 public void setComments(String comments) {
 getCurrency().setComments(comments);
 }
 @Override
 public int hashCode() {
 return getCurrency().hashCode();
 }
 @Override
 public boolean equals(Object obj) {
 if (obj == null) {
 return false;
 }
 if (!(obj instanceof CurrencyEntityAtJpa)) {
 throw new IllegalArgumentException(obj.toString()
 + " is not CurrencyEntityAtJPA object.");
 }
 return getCurrency().equals(((CurrencyEntityAtJpa) obj).getCurrency());
 }
}

Is this a good design for Hibernate entity where I want to separate business logic and classes which work with database?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jun 8, 2015 at 13:12
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I don't see too much of an advantage in separating like this. Especially when considering Basic Java Persistence API Best Practices, Access Fields Rather Than Properties:

I prefer to specify object-relational mapping by annotating entity fields directly, rather than annotating get/set methods (properties), for several reasons.

answered Jun 8, 2015 at 14:07
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.