What is the best practice for the type of paramaters of dao/repository method, entity-objects or entity-ids?
@Entity
class Product {
// ...
@ManyToOne
Seller seller;
}
@Entity
class Seller {
@Id @GeneratedValue
Long id;
}
class ProductDao {
// ...
// Using ids
public List<Product> getProductsOf(long sellerId) {
return getSession()
.createQuery("from Product where seller.id = ?")
.setLong(0, sellerId)
.list();
}
// Using object-references
public List<Product> getProductsOf(Seller seller) {
return getSession()
.createQuery("from Product where seller = ?")
.setEntity(0, seller)
.list();
}
// Using object-references using merge() on a detached object
public List<Product> getProductsOf2(Seller seller) {
Seller persistentSeller = getSession().merge(seller);
return getSession()
.createQuery("from Product where seller = ?")
.setEntity(0, seller)
.list();
}
// Using object-references using lock() on a detached object
public List<Product> getProductsOf3(Seller seller) {
getSession().buildLockRequest(LockOptions.NONE).lock(seller);
return getSession()
.createQuery("from Product where seller = ?")
.setEntity(0, seller)
.list();
}
}
I have found the following pros and cons, but I was wondering if there is a best practice among experienced Spring/Hibernate/JPA users.
getProductsOf(seller.getId())
getProductsOf(seller)
I'm using getProductsOf(Seller seller)
, but having to verify whether seller is in persistent or detached state is very cumbersome. Therefor, I'm thinking of using ids instead.
The best way is to avoid writing down your own DAO and use Spring Data instead.
I prefer the Spring Repository API, which looks like this:
public interface CrudRepository<T, ID extends Serializable>
extends Repository<T, ID> {
<S extends T> S save(S entity);
T findOne(ID primaryKey);
Iterable<T> findAll();
Long count();
void delete(T entity);
boolean exists(ID primaryKey);
}
save
and delete
methods take an entityfindOne
and exists
take an identifier because it assumes you don't have the entity that you want to fetchAs for findOne
, it's better to have it take an identifier. This way you can call it even if you have an entity. If it were taken an entity, then you'd have to create a transient entity with a populated identifier just for the sake of fetching the associated managed entity.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With