У меня есть объектная модель
@Table(name = "MOB_Objects")
public class ak_BankObject {
// private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@ManyToOne
private ak_Zones ak_zone;
@OneToMany(cascade = CascadeType.ALL)
/* (mappedBy="brfebranchid") */
@JoinTable(name = "mob_bankObj_branchF")
List<ak_BranchFeatures> ak_branchFeatures;
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "mob_bankObj_image")
List<ak_BranchImages> ak_branchImages;
@OneToMany
List<ak_BranchScore> BranchScore;
@OneToMany
List<ak_BranchComment> BranchComment;
@Column
private Integer objectid;
@Column
private String branchname;
@Column
private String branchcode;
@Column
private Integer branchtype;
@Column
private String branchchief;
@Column
private String postalcode;
@Column
private Integer branchdegree;
@Column
private String branchtel;
@Column
private String branchfax;
@Column
private String branchtelbank;
@Column
private String address;
@Column
private Integer objecttype;
@Column
private double latitude;
@Column
private double longitude;
@Column
private String codedevices;
public ak_Zones getAk_zone() {
return ak_zone;
}
public void setAk_zone(ak_Zones ak_zone) {
this.ak_zone = ak_zone;
}
public List<ak_BranchFeatures> getAk_branchFeatures() {
return ak_branchFeatures;
}
public void setAk_branchFeatures(List<ak_BranchFeatures> ak_branchFeatures) {
this.ak_branchFeatures = ak_branchFeatures;
}
public String getBranchname() {
return branchname;
}
public void setBranchname(String branchname) {
this.branchname = branchname;
}
public String getBranchcode() {
return branchcode;
}
public void setBranchcode(String branchcode) {
this.branchcode = branchcode;
}
public Integer getBranchtype() {
return branchtype;
}
public void setBranchtype(Integer branchtype) {
this.branchtype = branchtype;
}
public String getBranchchief() {
return branchchief;
}
public void setBranchchief(String branchchief) {
this.branchchief = branchchief;
}
public String getPostalcode() {
return postalcode;
}
public void setPostalcode(String postalcode) {
this.postalcode = postalcode;
}
public Integer getBranchdegree() {
return branchdegree;
}
public void setBranchdegree(Integer branchdegree) {
this.branchdegree = branchdegree;
}
public String getBranchtel() {
return branchtel;
}
public void setBranchtel(String branchtel) {
this.branchtel = branchtel;
}
public String getBranchfax() {
return branchfax;
}
public void setBranchfax(String branchfax) {
this.branchfax = branchfax;
}
public String getBranchtelbank() {
return branchtelbank;
}
public void setBranchtelbank(String branchtelbank) {
this.branchtelbank = branchtelbank;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getObjecttype() {
return objecttype;
}
public void setObjecttype(Integer objecttype) {
this.objecttype = objecttype;
}
public Integer getObjectid() {
return objectid;
}
public void setObjectid(Integer objectid) {
this.objectid = objectid;
}
public String getCodedevices() {
return codedevices;
}
public void setCodedevices(String codedevices) {
this.codedevices = codedevices;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public List<ak_BranchComment> getBranchComment() {
return BranchComment;
}
public void setBranchComment(List<ak_BranchComment> branchComment) {
BranchComment = branchComment;
}
public List<ak_BranchScore> getBranchScore() {
return BranchScore;
}
public void setBranchScore(List<ak_BranchScore> branchScore) {
BranchScore = branchScore;
}
public List<ak_BranchImages> getAk_branchImages() {
return ak_branchImages;
}
public void setAk_branchImages(List<ak_BranchImages> ak_branchImages) {
this.ak_branchImages = ak_branchImages;
}
@Override
public String toString() {
return "BankObject [id=" + id + ", lon=" + longitude + ", latitude="
+ latitude + "]";
}}
мой репозиторий:
public interface BankRepository extends CrudRepository<ak_BankObject, Long> {}
мой сервис:
@Service
public class BankService {
public List<ak_BankObject> searchInBbox(double minLon, double minLat, double maxLon,
double maxLat) {
List<ak_BankObject> banks = (List<ak_BankObject>) bankRepository.findAll();
List<ak_BankObject> inBoxBanks = new ArrayList<>();
for (int i = 0; i < banks.size(); i++) {
double lon = banks.get(i).getLongitude();
double lat = banks.get(i).getLatitude();
if (lon >= minLon && lon <= maxLon && lat >= minLat
&& lat <= maxLat) {
inBoxBanks.add(banks.get(i));
}
}
return inBoxBanks;
}}
и с данными весны я использую crudRepository, чтобы найти все в этом объекте, но у меня есть ошибка:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/MBFinder] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.spr.model.ak_BankObject.ak_branchFeatures, could not initialize proxy - no Session] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.spr.model.ak_BankObject.ak_branchFeatures, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:500)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at com.spr.model.ak_BankObject.toString(ak_BankObject.java:272)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at java.util.AbstractCollection.toString(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at com.spr.controller.BankController.searchNearest(BankController.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Я не хочу использовать EAGER, и я видел это решение, но не работал для меня. Есть ли способ вместо собственного запроса?
Причина, когда вы извлекаете атрибут на ленивой стороне, сеанс закрыт. Таким образом, вы не можете получить атрибут, и вы получите исключение.
3 для вас:
fetch = FetchType.EAGER
как fetch = FetchType.EAGER
.OpenSessionInView
для автоматического управления областью сеанса. Самый простой способ - просто пометить свой метод обслуживания с помощью @Transactional
. Это приведет к тому, что JPA EntityManager
будет открыт до тех пор, пока выполнение кода не покинет тело метода.
Если вам нужно получить доступ к ленивым отношениям вне этого метода (например, при визуализации представления), вам необходимо развернуть OpenEntityManagerInViewFilter
(на основе API-интерфейса Servlet) или OpenEntityManagerInViewInterceptor
(специально для Spring MVC).
Если решение OpenSessionInView
, предоставленное sgyyz, не работает, вы можете явно инициализировать ленивую ассоциацию.
for (int i = 0; i < banks.size(); i++) {
ak_BankObject bank = banks.get(i);
Hibernate.initialize(bank.getAk_branchFeatures());
double lon = bank.getLongitude();
double lat = bank.getLatitude();
if (lon >= minLon && lon <= maxLon && lat >= minLat && lat <= maxLat) {
inBoxBanks.add(bank);
}
}
Поскольку OpenSessionInView инициализирует ассоциацию один за другим, я считаю, что с точки зрения производительности это может быть эквивалентно.
Offtopic: ваша стратегия именования объектов не самая лучшая. Ваш банковский объект должен быть в стандартах именования OO - AkBankObject
(хранит Object
в названии, потому что это может быть требование бизнес-логики, если не его можно назвать AkBank
). То же самое для свойств объекта, ak_branchFeatures --> akBranchFeatures
. Если вы имеете дело с устаревшим кодом, мои соболезнования.