Я пишу веб-приложение (серверное приложение), где у меня есть слой дао, уровень обслуживания и уровень приложения.как я должен принять исключение отложенной инициализации, вызванное тем, что сущность, возвращаемая из дао-уровня, связана с сеансом, открытым внутри метода, из которого он возвращается, а также закрытым, что делает сущность отсоединенной.Следующая вещь - это безопасно разделять спящие сущности между различными уровнями.что заставляет меня задать этот вопрос, так это сценарий: например, предположим, что у меня есть находящийся в спящем состоянии объект, имеющий один к одному связь с некоторым другим объектом.и предположим, что дао передал его на сервисный уровень на прикладной уровень.Теперь, если я пытаюсь получить эту ассоциированную сущность на уровне приложения с помощью переданного метода получения сущности, запускается запрос к базе данных, который, я думаю, портит «разделение проблем», так как связанная с базой данных операция должна быть ограничена уровнем дао.я прав?
Я обнаружил упомянутую проблему во время модульного тестирования своего даослоя через базу данных в памяти.Мой сценарий, у меня есть один из класса pojo с именем RegisteredUser, имеющего поля: (id, имя пользователя, имя, фамилия, passwHash, электронная почта, StudyCentre).StudyCentre - это другая сущность, которая связана с RegistereUser отображением один на один, а имя пользователя - это Naturalid.Мне нужны 2 типа операций чтения, во-первых, мне нужно получить данные пользователя без учебного центра через натуральный идентификатор, а во-вторых, снова получить полные поля пользователя через натурал.хорошая идея сделать два отдельных DTO и передавать их по слоям.
RegisteredUser Entity:
package com.ignoubadhega.pojos;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.NaturalId;
@Entity
@Table(name = "registered_user")
@DynamicUpdate
public class RegisteredUser {
private Long dbUserId;
private String userName;
private String passwHash;
private String firstName;
private String lastName;
private String email;
private StudyCentre studyCentre;
RegisteredUser() {
}
public RegisteredUser(
String userName, String passwHash, String firstName,
String lastName, String email
) {
super();
this.userName = userName;
this.passwHash = passwHash;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "db_user_id")
public Long getDbUserId() {
return dbUserId;
}
@Override
public String toString() {
return "RegisteredUser [dbUserId="
+ dbUserId
+ ", userName="
+ userName
+ ", passwHash="
+ passwHash
+ ", firstName="
+ firstName
+ ", lastName="
+ lastName
+ ", email="
+ email
+ "]";
}
public void setDbUserId(Long dbUserId) {
this.dbUserId = dbUserId;
}
@Column(name = "username", nullable = false, unique = true)
@NaturalId
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Column(name = "passw_hash", nullable = false)
public String getPasswHash() {
return passwHash;
}
public void setPasswHash(String passwHash) {
this.passwHash = passwHash;
}
@Column(name = "first_name", nullable = false)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Column(name = "last_name", nullable = false)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Column(name = "email", nullable = false, unique = true)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "db_study_centre_id", nullable = false)
public StudyCentre getStudyCentre() {
return studyCentre;
}
public void setStudyCentre(StudyCentre studyCentre) {
this.studyCentre = studyCentre;
}
}
Dao Implementor:
package com.ignoubadhega.dao.impl;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.ignoubadhega.dao.RegisteredUserDAO;
import com.ignoubadhega.pojos.RegisteredUser;
public class RegisteredUserDAOImpl implements RegisteredUserDAO {
private SessionFactory sessionFactory;
public RegisteredUserDAOImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void addUser(RegisteredUser user) {
try (Session session = sessionFactory
.openSession()) {
session.beginTransaction();
session.persist(user);
session.getTransaction().commit();
} catch (HibernateException except) {
except.printStackTrace();
}
}
@Override
public RegisteredUser getUserByUserName(String username, boolean doesStudyCentereNeeded) {
try (Session session = sessionFactory
.openSession()) {
RegisteredUser user = session
.bySimpleNaturalId(RegisteredUser.class).load(username);
if (doesStudyCentereNeeded) {
user.setStudyCentre(user.getStudyCentre());
}
return user;
} catch (HibernateException except) {
except.printStackTrace();
}
return null;
}
@Override
public void deleteUser(RegisteredUser user) {
try (Session session = sessionFactory
.openSession()) {
session.beginTransaction();
session.delete(user);
session.getTransaction().commit();
} catch (HibernateException except) {
except.printStackTrace();
}
}
@Override
public void updateUser(RegisteredUser user) {
try (Session session = sessionFactory
.openSession()) {
session.beginTransaction();
session.update(user);
session.getTransaction().commit();
} catch (HibernateException except) {
except.printStackTrace();
}
}
}
TestCase, который находит проблемуотложенной инициализации:
@Test
@DisplayName(
"User through its natural id 'username' assuming the user"
+ " is persistent in the database is successful"
)
void test_fetching_a_persistent_user_through_username_is_successful() {
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
session.persist(user);
session.getTransaction().commit();
RegisteredUser retrievedUser =
dao.getUserByUserName("prav", true);
assertNotNull(retrievedUser);
assert_actual_user_and_retrieved_user_fields_are_equal(user,
retrievedUser);
} catch (HibernateException except) {
except.printStackTrace();
}
}
private static void assert_actual_user_and_retrieved_user_fields_are_equal(
RegisteredUser actualUser, RegisteredUser userRetrieved
) throws MultipleFailuresError {
assertAll("user fields",
() -> assertEquals(actualUser.getUserName(),
userRetrieved.getUserName()),
() -> assertEquals(actualUser.getPasswHash(),
userRetrieved.getPasswHash()),
() -> assertEquals(actualUser.getFirstName(),
userRetrieved.getFirstName()),
() -> assertEquals(actualUser.getLastName(),
userRetrieved.getLastName()),
() -> assertEquals(actualUser.getEmail(),
userRetrieved.getEmail()),
() -> {
StudyCentre retrievedCentre =
userRetrieved.getStudyCentre();
assertNotNull(retrievedCentre);
assertAll("user study centre assosciated",
() -> assertEquals(
actualUser.getStudyCentre().getData()
.getStudyCentreName(),
retrievedCentre.getData()
.getStudyCentreName()),
() -> assertEquals(
actualUser.getStudyCentre().getData()
.getRegionalCentreCode(),
retrievedCentre.getData()
.getRegionalCentreCode()));
});
}
Я хочу сохранить свой уровень обслуживания (еще не реализованный) изолированным от вещей, характерных для спящего режима, таких как сеансы и операции с базами данных (CRUD).Как я могу достичь этого.Есть ли шаблоны проектирования, которым я должен следовать.я новичок в спящем.пожалуйста, направьте меня, если я делаю что-то не так в любом месте.Я пытался найти похожие темы в Google, но не смог получить представление о проблеме.