gpt4 book ai didi

java - 当内容超过 141 个字符时,VARCHAR 列会安静地中断 Hibernate

转载 作者:行者123 更新时间:2023-12-03 11:20:22 25 4
gpt4 key购买 nike

我们在使用 Spring Boot (v2.1.5) 和 Hibernate (5.3.10) 时遇到了一个非常奇怪的问题。我们有一张 table DocumentRevision它有外键,例如Document -> DocumentRevision -> User .当我们获取 Document , DocumentRevision是急切获取的,并且 User是懒惰的。这在大多数情况下都能正常工作,但在非常具体的情况下以非常具体的方式失败。DocumentRevision实际上有两个外键 User :uploader (NOT NULL)approver (NULL) .DocumentRevision中的一列是 source VARCHAR(255) NULL .
DocumentRevision.source包含 142 个或更多字符的长度,uploader不被 Hibernate 获取,并且 NullPointerException结果。对于相同的记录,当 source列是 null或 0-141 个字符的长度,uploader正确获取。这是 100% 可重现的,142 个字符是突破点。请注意,这些是 ASCII 字符,没什么特别的(排序规则是 utf8mb4_unicode_ci )。

  • 完全填满所有其他 VARCHAR未损坏记录中的字段无效——一切正常(实际上只有 source 列会导致此问题,并且仅当它包含 142 个或更多字符时)
  • 我可以通过在 source 中插入 142 个或更多字符来打破未损坏的记录。栏目
  • 设置 approverIdnull对于一个 splinter 的记录修复问题
  • 将其设置为有效的用户 ID,但与 uploaderId 不同没有解决问题
  • 当两者 creatorapprover在数据库中保存完全相同的值(指向相同的 User ),hibernate 能够获取 approver但不是 creator -- 也就是说,当我检查结果 Document 时,其 DocumentRevision没有 creator ,但它确实有一个 approver -- 这仅在调试和检查值 时才是正确的。
  • 打开 SQL 日志显示为损坏的记录执行 X 条语句,为未损坏的记录执行 X+3 条语句——额外的 SQL 语句与获取用户有关(它们在损坏的情况下不会发生)

  • 调试失败
    我已经尝试了以下相同的结果。
  • 增加 source 的大小栏目
  • 替换 @Column带有 @Column(length = X) 的注释
  • 重命名表
  • 重命名列
  • 升级 Spring/Hibernate
  • 标记 uploaderFetchType.EAGER
  • 删除 optional = false来自 uploader

  • 更新:我们注意到,这也可以通过从 Document 中删除多对一关系来解决。至 DocumentRevision ( Document.documentRevisions )。此外,从 DocumentRevision 中删除一对一关系至 Document ( DocumentRevision.document ) 解决了这个问题。我目前的理论是某种循环引用——但同样,日志中没有任何来自 Hibernate 的内容。
    以下是一些片段:
    表:文档
    CREATE TABLE `Document` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `createdDateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `deletedDateTime` timestamp NULL DEFAULT NULL,
    `lastModifiedDateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `version` bigint(20) NOT NULL,
    `sectionId` int(11) NOT NULL,
    `currentRevisionId` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `FK_Document_sectionId_Section_id` (`sectionId`),
    KEY `FK_Document_currentRevisionId_DocumentRevision_id` (`currentRevisionId`),
    CONSTRAINT `FK_Document_currentRevisionId_DocumentRevision_id` FOREIGN KEY (`currentRevisionId`) REFERENCES `DocumentRevision` (`id`),
    CONSTRAINT `FK_Document_sectionId_Section_id` FOREIGN KEY (`sectionId`) REFERENCES `Section` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=34074 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    表:文档修订版
    CREATE TABLE `DocumentRevision` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `createdDateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `deletedDateTime` timestamp NULL DEFAULT NULL,
    `lastModifiedDateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `version` bigint(20) NOT NULL,
    `contentLength` bigint(20) DEFAULT NULL,
    `uploaderId` binary(16) NOT NULL,
    `approverId` binary(16) DEFAULT NULL,
    `fileId` int(11) NOT NULL,
    `parsed` tinyint(1) NOT NULL DEFAULT '0',
    `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
    `source` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `sourcePublishDateTime` timestamp NULL DEFAULT NULL,
    `description` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `coordinateSystem` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
    `mgrs` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `latitude` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `longitude` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `location` point DEFAULT NULL,
    `sourceUrl` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `marking` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
    `approvedDateTime` timestamp NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `FK_DocumentRevision_fileId_Document_id` (`fileId`),
    KEY `FK_DocumentRevision_uploaderId_User_id` (`uploaderId`),
    KEY `FK_DocumentRevision_approverId_User_id` (`approverId`),
    CONSTRAINT `FK_DocumentRevision_approverId_User_id` FOREIGN KEY (`approverId`) REFERENCES `User` (`id`),
    CONSTRAINT `FK_DocumentRevision_fileId_Document_id` FOREIGN KEY (`fileId`) REFERENCES `Document` (`id`),
    CONSTRAINT `FK_DocumentRevision_uploaderId_User_id` FOREIGN KEY (`uploaderId`) REFERENCES `User` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=34080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    表:用户
    CREATE TABLE `User` (
    `id` binary(16) NOT NULL,
    `createdDateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `deletedDateTime` timestamp NULL DEFAULT NULL,
    `lastModifiedDateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `version` bigint(20) NOT NULL,
    `active` tinyint(1) NOT NULL,
    `firstName` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
    `lastName` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
    `username` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
    `primaryEmailAddress` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `hidden` tinyint(1) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    UNIQUE KEY `IDX_Person_username` (`username`),
    KEY `IDX_Person_primaryEmailAddress` (`primaryEmailAddress`),
    KEY `IDX_Person_lastName` (`lastName`),
    KEY `IDX_Person_firstName` (`firstName`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    映射:文档
    @Entity
    @Table(name = "Document")
    @Data
    @EqualsAndHashCode(callSuper = true)
    public class Document extends BaseEntity<Integer>
    {
    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "sectionId")
    private Section section;

    @ManyToOne(cascade = CascadeType.REMOVE)
    @JoinColumn(name = "currentRevisionId")
    private DocumentRevision currentRevision;

    @OneToMany(mappedBy = "document", cascade = CascadeType.REMOVE)
    private List<DocumentRevision> documentRevisions = new ArrayList<>();
    }
    映射:文档修订
    @Entity
    @Table(name = "DocumentRevision")
    @Data
    @EqualsAndHashCode(callSuper = true)
    public class DocumentRevision extends BaseEntity<Integer>
    {
    @JsonIgnore
    @ManyToOne
    @JoinColumn(name = "documentId", nullable = false)
    private Document document;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "uploaderId")
    private User uploader;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "approverId")
    private User approver;

    @Column
    private String source;

    // other fields removed for brevity
    }
    映射:用户
    @EqualsAndHashCode
    @Data
    @Entity
    @Table(name = "User")
    public class User extends BaseEntity<UUID>
    {
    @Column(length = 60, nullable = false)
    private String username;

    @Column(length = 25, nullable = false)
    private String firstName;

    @Column(length = 25, nullable = false)
    private String lastName;

    @Column(length = 255)
    private String primaryEmailAddress;

    @Column(nullable = false)
    private boolean active;

    @Column(nullable = false)
    private boolean hidden;
    }
    我意识到这是很多信息,但这让我难住了!

    最佳答案

    不久前我们又遇到了这个问题,然后就在上周。我做了更多的事情,并能够通过从 6.0.6 升级 MySQL 连接器依赖项来修复它。至 8.0.22 .

    关于java - 当内容超过 141 个字符时,VARCHAR 列会安静地中断 Hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57815740/

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