gpt4 book ai didi

angularjs - Jackson 混淆了双向一对多关系 : failed to lazily initialize collection

转载 作者:行者123 更新时间:2023-12-04 13:59:28 35 4
gpt4 key购买 nike

后端 Spring MVC 和 Spring-data,spring-security 。前端 Angularjs。我使用的是 spring 3.1;Jackson 1.8; JPa 2.1 ands mysql.基本问题同问多次。我有一个带有两个 POJO 站点和 typeSite 的简单程序,其中一个 typeSite 可以有多个站点。但我收到以下错误:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: TypeSites.sitees, could not initialize proxy - no Session (through reference chain: vo.TypeSitesListVO["typesites"]->java.util.UnmodifiableRandomAccessList[0]-model.TypeSites["sitees"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: model.TypeSites.sitees, could not initialize proxy - no Session (through reference chain:vo.TypeSitesListVO["typesites"]->java.util.UnmodifiableRandomAccessList[0]->model.TypeSites["sitees"])   
Caused by: com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: model.TypeSites.sitees, could not initialize proxy - no Session (through reference chain: vo.TypeSitesListVO["typesites"]->java.util.UnmodifiableRandomAccessList[0]->model.TypeSites["sitees"])

浏览器中出现以下错误:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)

所以为了更好地理解这个错误,让我们看看 JPA/Hibernate 如何处理这种关系。
每次我们在数据库中进行查询时,JPA 都会带入该类的所有信息。这条规则的异常(exception)是当我们谈论列表(集合)时。
请注意,在上面的代码中,数据库查询将返回一个 Sitesobject。当我访问站点集合时,容器会注意到站点集合是一个惰性属性,它会“要求”JPA 从数据库中加载这个集合。

在查询(将带来网站集)执行的那一刻,将发生异常。当 JPA/Hibernate 尝试访问数据库以获取此惰性信息时,JPA 会注意到没有打开的集合。这就是发生异常的原因,即缺少打开的数据库连接。

模型类:
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Sites implements java.io.Serializable {

private static final long serialVersionUID = 1L;
private int id;
private TypeSites siteesTypeSite;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
//@ManyToOne(fetch = FetchType.LAZY)
//@JoinColumn(name ="idTypeSite")
//@JsonIgnore
@JsonBackReference("site-typeSite")
@ManyToOne
@JoinColumn(name = "idTypeSite", foreignKey = @ForeignKey(name = "fk_site_typeSite"))
public TypeSites getSiteesTypeSite() {
return siteesTypeSite;
}
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="idTypeSite")
public class TypeSites implements java.io.Serializable {
private int idTypeSite;
private Set<Sites> sitees= new HashSet<Sites>(0);

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getIdTypeSite() {
return idTypeSite;
}
//@JsonSerialize(using = CustomListSerializer.class)
//@JsonView(Views.Internal.class)
//@JsonIgnore
@JsonManagedReference("site-typeSite")
@OneToMany(mappedBy = "siteesTypeSite", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
public Set<Sites> getSitees() {
return sitees;
}

值对象设计模式代码
public class TypeSitesListVO {
private int pagesCount;
private long totalTypeSite;
private String actionMessage;
private String searchMessage;
private List<TypeSites> typesites;
//setters/gtters}
public class SitesListVO {
private int pagesCount;
private long totalSites;
private String actionMessage;
private String searchMessage;
private List<Sites> sites = new ArrayList<Sites>();
//setters/gtters}

存储库:
public interface SitesRepository extends PagingAndSortingRepository<Sites, Integer> {
//@Query("SELECT s FROM Sites s TypeSites ts JOIN FETCH s.siteesTypeSite WHERE s.id =ts.idTypeSite ")
//@EntityGraph(value = "sites.type", type = EntityGraphType.LOAD)
Page<Sites> findBycodeGSMLike(Pageable pageable, String codeGSM);
//Page<Sites> findBycodeGSMLike(Pageable pageable, List<String> codeGSM);
}

服务类:
@Service
@Transactional
public class SitesService {
@Autowired
private SitesRepository siteRepository;
@Transactional(readOnly = true)
public SitesListVO findAll(int page, int maxResults) {
Page<Sites> result = executeQueryFindAll(page, maxResults);
if(shouldExecuteSameQueryInLastPage(page, result)){
int lastPage = result.getTotalPages() - 1;
// for (Sites e: result){
// Hibernate.initialize(e.getSiteesTypeSite());
// }
result = executeQueryFindAll(lastPage, maxResults);
}
return buildResult(result);
}
public void save(Sites site) {
siteRepository.save(site);
}
@Transactional(readOnly = true)
public SitesListVO findBycodeGSMLike(int page, int maxResults, String codeGSM) {
Page<Sites> result = executeQueryFindByName(page, maxResults, codeGSM);

if(shouldExecuteSameQueryInLastPage(page, result)){
int lastPage = result.getTotalPages() - 1;
// for (Sites e: result){
// Hibernate.initialize(e.getSiteesTypeSite());
// }
result = executeQueryFindByName(lastPage, maxResults, codeGSM);
}
return buildResult(result);
}
private boolean shouldExecuteSameQueryInLastPage(int page, Page<Sites> result) {
return isUserAfterOrOnLastPage(page, result) && hasDataInDataBase(result);
}
private Page<Sites> executeQueryFindAll(int page, int maxResults) {
final PageRequest pageRequest = new PageRequest(page, maxResults, sortBycodeGSMASC());
// Page<Sites> SitesList = siteRepository.findAll(pageRequest);
// for (Sites e: SitesList){
// Hibernate.initialize(e.getSiteesTypeSite());
// }
// return SitesList;
return siteRepository.findAll(pageRequest);
}

private Sort sortBycodeGSMASC() {
return new Sort(Sort.Direction.ASC, "codeGSM");
}

private SitesListVO buildResult(Page<Sites> result) {

return new SitesListVO(result.getTotalPages(), result.getTotalElements(), result.getContent());
}

private Page<Sites> executeQueryFindByName(int page, int maxResults, String codeGSM) {
final PageRequest pageRequest = new PageRequest(page, maxResults, sortBycodeGSMASC());

// Page<Sites> SitesList = siteRepository.findBycodeGSMLike(pageRequest, codeGSM);
// for (Sites e: SitesList){
// Hibernate.initialize(e.getSiteesTypeSite());
// }
// return SitesList;
return siteRepository.findBycodeGSMLike(pageRequest, codeGSM);
}
private boolean isUserAfterOrOnLastPage(int page, Page<Sites> result) {
return page >= result.getTotalPages() - 1;
}

private boolean hasDataInDataBase(Page<Sites> result) {
return result.getTotalElements() > 0;
}
}

Controller 类:
@Controller
@RequestMapping(value = "/protected/sites")
public class SitesController {
private static final String DEFAULT_PAGE_DISPLAYED_TO_USER = "0";
@Autowired
private SitesService siteService;
@Autowired
private MessageSource messageSource;

@Value("5")
private int maxResults;

@RequestMapping(method = RequestMethod.GET)
public ModelAndView welcome() {
return new ModelAndView("sitesList");
}
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<?> listAll(@RequestParam int page, Locale locale) {

return createListAllResponse(page, locale);
}

@RequestMapping(method = RequestMethod.POST, produces = "application/json")
public ResponseEntity<?> create(@ModelAttribute("site") Sites site,
@RequestParam(required = false) String searchFor,
@RequestParam(required = false,
defaultValue = DEFAULT_PAGE_DISPLAYED_TO_USER) int page,
Locale locale) {
siteService.save(site);

if (isSearchActivated(searchFor)) {
return search(searchFor, page, locale, "message.create.success");
}

return createListAllResponse(page, locale, "message.create.success");
}


private SitesListVO listAll(int page) {
return siteService.findAll(page, maxResults);
}
private ResponseEntity<SitesListVO> returnListToUser(SitesListVO siteList) {
return new ResponseEntity<SitesListVO>(siteList, HttpStatus.OK);
}
private ResponseEntity<?> createListAllResponse(int page, Locale locale) {
SitesListVO siteListVO = listAll(page);
return createListAllResponse(page, locale, null);
}

private ResponseEntity<?> createListAllResponse(int page, Locale locale, String messageKey) {
SitesListVO siteListVO = listAll(page);
addActionMessageToVO(siteListVO, locale, messageKey, null);
return returnListToUser(siteListVO);
}
private SitesListVO addActionMessageToVO(SitesListVO siteListVO, Locale locale, String actionMessageKey, Object[] args) {
if (StringUtils.isEmpty(actionMessageKey)) {
return siteListVO;
}
siteListVO.setActionMessage(messageSource.getMessage(actionMessageKey, args, null, locale));
return siteListVO;
}
private SitesListVO addSearchMessageToVO(SitesListVO siteListVO, Locale locale, String actionMessageKey, Object[] args) {
if (StringUtils.isEmpty(actionMessageKey)) {
return siteListVO;
}
siteListVO.setSearchMessage(messageSource.getMessage(actionMessageKey, args, null, locale));
return siteListVO;
}
private boolean isSearchActivated(String searchFor) {
//return !CollectionUtils.isEmpty(searchFor);
return !StringUtils.isEmpty(searchFor);
}
}

AngularJs 代码:
$scope.getContactList = function () {
var url = $scope.url;
$scope.lastAction = 'list';

$scope.startDialogAjaxRequest();

var config = {params: {page: $scope.pageToGet}};

$http.get(url, config)

.success(function (data) {
// console.log(data);
console.debug(data);
$scope.finishAjaxCallOnSuccess(data, null, false);
})
.error(function () {
$scope.state = 'error';
$scope.displayCreateContactButton = false;
});
}
$scope.populateTable = function (data) {
if (data.pagesCount > 0) {
$scope.state = 'list';

$scope.page = {source: data.sites, currentPage: $scope.pageToGet, pagesCount: data.pagesCount, totalContacts : data.totalContacts};

if($scope.page.pagesCount <= $scope.page.currentPage){
$scope.pageToGet = $scope.page.pagesCount - 1;
$scope.page.currentPage = $scope.page.pagesCount - 1;
}

$scope.displayCreateContactButton = true;
$scope.displaySearchButton = true;
} else {
$scope.state = 'noresult';
$scope.displayCreateContactButton = true;

if(!$scope.searchFor){
$scope.displaySearchButton = false;
}
}
if (data.actionMessage || data.searchMessage) {
$scope.displayMessageToUser = $scope.lastAction != 'search';

$scope.page.actionMessage = data.actionMessage;
$scope.page.searchMessage = data.searchMessage;
} else {
$scope.displayMessageToUser = false;
}
}

在spring mvc XML中,我有:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>

<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="filter.HibernateAwareObjectMapper" />
</property>
</bean>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
</list>
</property>
</bean>

HibernateAwareObjectMapper 类的代码:
公共(public)类 HibernateAwareObjectMapper 扩展 ObjectMapper {
    private static final long serialVersionUID = 1L;

public HibernateAwareObjectMapper() {
registerModule(new Hibernate4Module());
}

}

Web XML 我有这个过滤器:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

;
我正在使用以下依赖项:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate4</artifactId>
<version>2.4.0</version>
</dependency>

有没有办法通过 Open Session 加载集合?
提前谢谢你重播

最佳答案

我通过添加这个注释来解决这个问题 @LazyCollection(LazyCollectionOption.FALSE)

    //@JsonSerialize(using = CustomListSerializer.class)
//@JsonView(Views.Internal.class)
//@JsonIgnore
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "siteesTypeSite", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
public Set<Sites> getSitees() {
return sitees;
}

关于angularjs - Jackson 混淆了双向一对多关系 : failed to lazily initialize collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30465748/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com