Я хочу реализовать некоторые функции для получения текущего пользователя, вошедшего в систему (сущность JPA, представляющая человека, вошедшего в систему).Но вместо того, чтобы делать это классическим способом
CurrentUserService.getCurrentUser(){load the user from db by login})
Я хочу сделать это более CDI-способом.
Я хочу иметь CurrentUserFactory
, который предоставляет текущему пользователю какbean-объект с областью запроса, доступный с пользовательским квалификатором (текущий bean-компонент).
Qualifier:
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface CurrentUser {
}
Фабрика:
@Component
public class CurrentUserFactory {
@CurrentUser
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public User currentUser() throws IllegalStateException {
return
<DoWhatIMean>
User load form DB by:
SecurityContextHolder.getContext().getAuthentication().getName()
</dwim>
}
Использование:
@Controller
@RequestMapping(…)
public AccountController() {
@Resource
@CurrentUser
private User currentUser;
@RequestMapping(params=”my”)
public String myAccount () {
return “redirect:/account/”+currentUser.id;
}
}
Это отлично работает.
Но это не удастся (за исключением действительно полезных исключений), если я использую текущего пользователя для прямого JPA (Hibernate), такого как поиск сущности по ссылке на currentUser или сохранение сущности с помощьюссылка на currentUser.- ( Этот сбой понятен. )
Причина в том, что пружина вводит прокси CGI в currentUser.Это работает нормально, пока кто-то использует только свойства этого прокси, но терпит неудачу, если начинает использовать саму ссылку.
Я знаю, что работаю на краю спецификации, и я принимаю, если мойидея не работает.Но я хочу спросить вас, у меня есть идея, чтобы это заработало.Так что разработчик может использовать этот объект currentUser как обычный загруженный JPA объект.
По крайней мере, я хочу, чтобы это было очень простое использование только текущего пользователя:
@Resouce
@CurrenctUser
User currentUser;
и все..
Может, у кого-нибудь есть идея заставить его работать, например, трюк AspectJ (я использую время компиляции AspectJ)?
В любом случае: как я уже говорил, исключения являютсяне моя проблема, я понимаю их, потому что они являются только индикаторами описанной проблемы.
Исключение при попытке загрузки с помощью currentUser (Select b From Bookmark b Where user=?
)
java.lang.IllegalStateException
: org.hibernate.TransientObjectException
: объект ссылается на несохраненный временный экземпляр - сохраните временный экземпляр перед сбросом: domain.User
Исключение при попытке сохранить закладку (в закладке есть поле user)
не удалось вставить: [domain.Bookmark
];SQL [insert into bookmark (businessId, reference_Folder_fk, title, user_fk) values (?, ?, ?, ?)
];ограничение [null
];вложенное исключение org.hibernate.exception.ConstraintViolationException
: не удалось вставить: [domain.Bookmark
]