英文:
How can I avoid duplicate code with the same method body but different return types in Java?
问题
以下是您提供的内容的翻译部分:
想法:
当我在使用 Hibernate 时,我发现每次都需要编写某种代码。所以我将它们移到另一个方法作为包装器。在那里,将会有一个作为参数的函数接口,这样我就可以在这些上下文方法中添加一些代码。
问题:
这是我的两个方法。一个返回 Object,而另一个返回 List。我如何精确地泛化并使这两个方法合为一个,以避免代码重复。
public Object objectReturnContext(Function<Session, Object> function) {
// ...
}
public List<T> listReturnContext(Function<Session, List<T>> function) {
// ...
}
更好地理解,这是我的整个类。如果有人能给我提供更好的方法,我将非常感激。我已经在这个问题上花了几天时间。
package com.go_task.database;
import javax.persistence.Table;
// ... (其他 import 语句)
public abstract class QueryExecutionContext <T> {
// ...
// (其他方法和属性)
}
我已经在 BaseDaoImpl.java 中扩展了 QueryExecutionContext。所以我需要知道两件事。
- 我的方法是否可行。我在这里使用的是纯 Hibernate,没有使用 Spring Boot。
- 如果可以的话,请告诉我如何解决 objectReturnContext() 和 listReturnContext() 方法中的代码重复问题。
英文:
The Idea:
When I was using hibernate I saw that everytime I had to write some sort of code. So I moved them to another method as wrapper. Where there will be functional interface as argument so that I can append some code in those context methods.
Problem:
Here is my two methods. One returns Object while another one is returning List. How can I exactly generify and make those two methods as one so that I can avoid code duplication.
public Object objectReturnContext(Function<Session, Object> function) {
Object object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
public List<T> listReturnContext(Function<Session, List<T>> function) {
List<T> object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
For better understanding, This is my whole class. If anyone can advice me any better way I will be very thankful. I have been into this for last few days.
package com.go_task.database;
import javax.persistence.Table;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import javax.persistence.NoResultException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public abstract class QueryExecutionContext <T> {
public Class<T> entity;
public String tableName;
public QueryExecutionContext(Class<T> entity) {
this.entity = entity;
this.tableName = entity.getAnnotation(Table.class).name();
}
public List<T> criteriaContext(CriteriaContextRunner<Session, Root<T>,
CriteriaQuery<T>, CriteriaBuilder, List<T>> runner) {
List<T> data = new ArrayList<>();
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery =
criteriaBuilder.createQuery(entity);
Root<T> root = criteriaQuery.from(entity);
data = runner.apply(session, root, criteriaQuery, criteriaBuilder);
transaction.commit();
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return data;
}
public Object singleCriteriaContext(CriteriaContextRunner<Session, Root<T>,
CriteriaQuery<T>, CriteriaBuilder, Object> runner) {
Object data = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery =
criteriaBuilder.createQuery(entity);
Root<T> root = criteriaQuery.from(entity);
data = runner.apply(session, root, criteriaQuery, criteriaBuilder);
transaction.commit();
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return data;
}
public Object objectReturnContext(Function<Session, Object> function) {
Object object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
public List<T> listReturnContext(Function<Session, List<T>> function) {
List<T> object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
public void noReturnContext(Consumer<Session> consumer) {
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
consumer.accept(session);
transaction.commit();
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
}
}
I have extented QueryExecutionContext in my BaseDaoImpl.java later on. So I need to know 2 things.
- Is my approch is ok or not. Im using pure hibernate and nothing else. No spring boot here.
- If so then tell me how can I solve the code duplication in objectReturnContext() and listReturnContext() method.
答案1
得分: 8
Object
/List<T>
参数可以是泛型参数 U
:
public <U> U returnContext(Function<Session, U> function) {
U object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
U
将根据您传递给方法的 function
参数进行推断。如果像这样调用它:
Object o = returnContext(s -> {
...
return new Object(); // 仅为示例
});
那么 U
就是 Object
。
如果像这样调用它:
List<T> list = returnContext(s -> {
...
return new ArrayList<T>(); // 仅为示例
});
那么 U
就是 ArrayList<T>
。
英文:
The Object
/List<T>
parameter could be a generic parameter U
:
public <U> U returnContext(Function<Session, U> function) {
U object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
U
will be inferred depending on what function
you pass into the method. If you call it like:
Object o = returnContext(s -> {
...
return new Object(); // just an example
});
Then U
is Object
.
If you call it like:
List<T> list = returnContext(s -> {
...
return new ArrayList<T>(); // just an example
});
Then U
is ArrayList<T>
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论