gpt4 book ai didi

java - 当加载 spring-boot 和 spring-data-jpa 时,Hibernate 无法加载 JPA 2.1 Converter

转载 作者:太空狗 更新时间:2023-10-29 22:57:24 25 4
gpt4 key购买 nike

我有一个用于 UUID 的自定义转换器,可以将其转换为字符串而不是二进制文件:

package de.kaiserpfalzEdv.commons.jee.db;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.UUID;

@Converter(autoApply = true)
public class UUIDJPAConverter implements AttributeConverter<UUID, String> {
@Override
public String convertToDatabaseColumn(UUID attribute) {
return attribute.toString();
}

@Override
public UUID convertToEntityAttribute(String dbData) {
return UUID.fromString(dbData);
}
}

转换器(我还有其他一些专门用于时间/日期处理的转换器)驻留在库 .jar 文件中。

然后我在 .jar 文件中有实体。就像这个:

package de.kaiserpfalzEdv.office.core.security;

import de.kaiserpfalzEdv.commons.jee.db.OffsetDateTimeJPAConverter;
import de.kaiserpfalzEdv.commons.jee.db.UUIDJPAConverter;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Entity
@Table(
name = "tickets"
)
public class SecurityTicket implements Serializable {
private final static ZoneId TIMEZONE = ZoneId.of("UTC");
private final static long DEFAULT_TTL = 600L;
private final static long DEFAULT_RENEWAL = 600L;

@Id @NotNull
@Column(name = "id_", length=50, nullable = false, updatable = false, unique = true)
@Convert(converter = UUIDJPAConverter.class)
private UUID id;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "account_id_", nullable = false, updatable = false, unique = true)
private Account account;

@Convert(converter = OffsetDateTimeJPAConverter.class)
@Column(name = "created_", nullable = false, updatable = false)
private OffsetDateTime created;

@Convert(converter = OffsetDateTimeJPAConverter.class)
@Column(name = "validity_", nullable = false, updatable = false)
private OffsetDateTime validity;


@Deprecated
public SecurityTicket() {
}


public SecurityTicket(@NotNull final Account account) {
id = UUID.randomUUID();
this.account = account;
created = OffsetDateTime.now(TIMEZONE);
validity = created.plusSeconds(DEFAULT_TTL);
}


public void renew() {
validity = OffsetDateTime.now(TIMEZONE).plusSeconds(DEFAULT_RENEWAL);
}

public boolean isValid() {
OffsetDateTime now = OffsetDateTime.now(TIMEZONE);

System.out.println(validity.toString() + " is hopefully after " + now.toString());

return validity.isAfter(now);
}

public UUID getId() {
return id;
}

public OffsetDateTime getValidity() {
return validity;
}

public String getAccountName() {
return account.getAccountName();
}

public String getDisplayName() {
return account.getDisplayName();
}

public Set<String> getRoles() {
HashSet<String> result = new HashSet<>();

account.getRoles().forEach(t -> result.add(t.getDisplayNumber()));

return Collections.unmodifiableSet(result);
}

public Set<String> getEntitlements() {
return Collections.unmodifiableSet(new HashSet<>());
}


@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
SecurityTicket rhs = (SecurityTicket) obj;
return new EqualsBuilder()
.append(this.id, rhs.id)
.isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder()
.append(id)
.toHashCode();
}


@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("id", id)

.append("account", account)
.append("validity", validity)
.toString();
}
}

当通过 maven 和 testng 运行集成测试时,数据库工作得很好。但是当我启动应用程序(第三个 .jar 文件)时,我得到一个讨厌的异常,归结为:

Caused by: org.hibernate.HibernateException: Wrong column type in kpoffice.tickets for column id_. Found: varchar, expected: binary(50)
at org.hibernate.mapping.Table.validateColumns(Table.java:372)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1338)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:175)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:525)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
... 120 more

convert 的autoApply 不起作用。我试图将转换器注释到类和属性本身。但是没有使用转换器。但是当我通过 hibernate 特定注释添加 hibernate UUID 类型时,hibernate 提示说它不能为同一属性提供转换器和 hibernate 类型定义。所以 hibernate 读取转换器配置。

使用 envers 时,JPA 2.1 转换器不工作。但我不在我的软件中使用 envers。

我希望有人知道我做错了什么......

最佳答案

Andy Wilkinson gave the correct answer.阅读规范在很多时候都有帮助。

JPA 2.1 转换器不适用于 @Id 注释属性。

谢谢安迪。

关于java - 当加载 spring-boot 和 spring-data-jpa 时,Hibernate 无法加载 JPA 2.1 Converter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28337798/

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