Вы можете решить проблему с помощью AbstractInsertable<T>
-класса, в котором есть некоторый public boolean insert(T t)
, содержащий ваш код:
public abstract class AbstractInsertable<T> extends ... {
public boolean insert(T t) {
Session session = null;
try {
session = super.getConnection();
session.getTransaction().begin();
session.save(t);
session.getTransaction().commit();
return true;
} catch (HibernateException e) {
e.printStackTrace();
return false;
} finally {
closeConnection(session);
}
}
[...]
}
Реализации затем могут наследоваться от этого AbstractInsertable<T>
, например CategorieDaoImpl extends AbstractInsertable<Category>
.Это, конечно, работает только до тех пор, пока вы наследуете только от одного класса.
Другой альтернативой будет работа с интерфейсами и реализациями по умолчанию.
Ответ на этом заканчивается.Остальное мое личное мнение.
Мое личное желание было бы для Java разрешить множественное наследование для этих точных проблем: вы могли бы определить classs для каждой CRUD-операции и использовать их как миксины в Dao
-implementations.Методы по умолчанию в интерфейсах довольно близки к мульти-наследованию, но имеют некоторые ограничения, например, все методы должны быть public
, а атрибуты не могут быть определены, чего не было бы при мульти-наследовании.
Незначительное замечание в вашем коде: у вас есть возможность возникновения NullPointerException
:
Session session = null;
try {
session = super.getConnection();
[...]
} finally {
closeSession(session);
}
Не зная точной реализации closeSession(...)
, я не удивлюсь, если вы не выполняетеnullcheck, таким образом, NPE
может быть брошено.Если Session
является AutoCloseable
, вы можете использовать try-with-resources
.Если это не так, вы можете использовать Optional
в своих интересах:
Optional<Session> optionalSession = Optional.empty();
try {
optionalSession = Optional.of(super.getConnection());
session = optionalSession.get();
[...]
} finally {
optionalSession.ifPresent(this::closeSession);
}