| 知乎专栏 |
{"status":false,"code":"HttpMessageNotWritableException","data":null,"reason":"Could not write JSON: failed to lazily initialize a collection of role: cn.netkiller.domain.Lora.keyword: could not initialize proxy - no Session"}⏎
@ElementCollection(fetch = FetchType.EAGER)
private Set<String> keyword = new HashSet<String>();
查询 version 表中的最有一条记录,提示 Query did not return a unique result: 2 results were returned
package cn.netkiller.domain;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
@Entity
@Table
@DynamicUpdate
@DynamicInsert
@Data
@Comment("版本表")
public class Version implements Serializable {
@Serial
public static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false, insertable = false, updatable = false, columnDefinition = "int unsigned")
@Comment("主键")
private Integer id;
@Comment("产品")
@Column(columnDefinition = "enum('Phone','Tablet','Badges','Watch') DEFAULT 'Tablet'")
private String product;
@Comment("版本")
@Column(length = 5)
private String version;
@Comment("下载地址")
private String url;
@Column(insertable = false, updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
@Comment("创建时间")
private Date ctime;
@Column(nullable = true, insertable = false, updatable = false, columnDefinition = "TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP")
@Comment("修改时间")
private Date mtime;
}
接口定义 findOneBy 查询 version 表中存在多条记录,我们只要最后一条,所以不能使用 findOneBy,需要使用 findFirstBy
package cn.netkiller.repository;
import cn.netkiller.domain.Version;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface VersionRepository extends CrudRepository<Version, Integer> {
Iterable<Version> findByProduct(String tablet);
Optional<Version> findOneByProductOrderByIdDesc(String tablet);
}
package cn.netkiller.repository;
import cn.netkiller.domain.Version;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface VersionRepository extends CrudRepository<Version, Integer> {
Iterable<Version> findByProduct(String tablet);
Optional<Version> findFirstByProductOrderByIdDesc(String tablet);
}
@GetMapping("/version/tablet/latest")
public AigcResponse tabletLatest() {
Optional<Version> optional = versionRepository.findFirstByProductOrderByIdDesc("Tablet");
if (optional.isPresent()) {
Version version = optional.get();
log.debug(version.toString());
return new AigcResponse(version);
}
return new AigcResponse(null);
}
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query
package cn.netkiller.repository;
import cn.netkiller.domain.Picture;
import io.lettuce.core.dynamic.annotation.Param;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface PictureRepository extends JpaRepository<Picture, Long> {
@Query("UPDATE Picture SET share = :status WHERE id=:id")
@Modifying
int updateShareStatus(@Param("id") Long id, @Param("status") boolean status);
}
Service
public int share(Long id, boolean status) {
return pictureRepository.updateShareStatus(id, status);
}
解决方案,再 Server 方法增加事务注解
@Transactional(rollbackFor = Exception.class)
public int share(Long id, boolean status) {
return pictureRepository.updateShareStatus(id, status);
}
第一种解决方法,捕捉 LazyInitializationException 异常
@Cacheable(value = "picture:click", key = "#deviceId+'-'+#pictureId", unless = "#result == null")
public Optional<PictureClick> click(Integer deviceId, Integer pictureId) {
Optional<PictureClick> optional = pictureClickRepository.findByDeviceIdAndPictureId(deviceId, pictureId);
optional.ifPresent(pictureClick -> {
try {
log.debug(pictureClick.toString());
} catch (LazyInitializationException e) {
log.error(e.getMessage());
}
});
return optional;
}
第二种解决方法 FetchType.EAGER
@ManyToOne(fetch = FetchType.EAGER, optional = false)
第三种解决方法 @Transactional(readOnly = true)
@Transactional(readOnly = true)
public Optional<PictureClick> click(Integer deviceId, Integer pictureId) {
Optional<PictureClick> optional = pictureClickRepository.queryByDeviceIdAndPictureId(deviceId, pictureId);
optional.ifPresent(pictureClick -> {
try {
log.debug(pictureClick.toString());
} catch (LazyInitializationException e) {
log.error(e.getMessage());
}
});
return optional;
}
第四种解决方法 @Proxy(lazy = false)
@Proxy(lazy = false) 的意思和FetchType.EAGER类似
JDBC exception executing SQL [select p1_0.id,p1_0.audio,p1_0.audit,p1_0.bmp,p1_0.ctime,p1_0.device,p1_0.english,p1_0.favorites,p1_0.forward,p1_0.group_id,p1_0.image,p1_0.likes,p1_0.mtime,p1_0.picture_group_id,p1_0.pinyin,p1_0.prompt,p1_0.session,p1_0.share,p1_0.story,p1_0.thumbnail,p1_0.translate from picture p1_0 where p1_0.audit=1 and p1_0.share=1 group by coalesce(p1_0.picture_group_id,p1_0.session) limit ?,?] [Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'watch.p1_0.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by] [n/a]; SQL [n/a]
解决方案一,使用 ANY_VALUE() 函数
@Query(" SELECT ANY_VALUE(p.id), ANY_VALUE(p.story), ANY_VALUE(p.image) FROM Picture p WHERE p.audit = true AND p.share = true GROUP BY IFNULL(p.pictureGroup.id,p.session)")
Page<Picture> queryGroup(Pageable pageable);
解决方案二,修改数据库配置
SET sql_mode='';
SELECT id,name,group_id FROM test.photograph group by group_id;
SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
@GetMapping("discovery/group")
// @Deprecated(since = "v4.0.0", forRemoval = true)
public AigcResponse group(Pageable pageable) {
Page<Map<String, Object>> page = pictureGroupService.discoveryPictureGroup(pageable);
List<Map<String, Object>> newList = new ArrayList<Map<String, Object>>();
List<Map<String, Object>> contents = page.getContent();
contents.forEach(content -> {
Map<String, Object> map = new HashMap<String, Object>(content);
map.put("thumbnail", url.concat((String) map.get("thumbnail")));
newList.add(map);
});
Page<Map<String, Object>> newPage = new PageImpl<>(newList, pageable, page.getTotalElements());
return new AigcResponse(newPage);
}