Hibernate:与两个@ JoinColumn的关系的MappingException以及其中一个列的附加PK只读映射

Kaw*_*awu 5 mapping hibernate jpa

请注意以下数据库设计:

数据库设计

注意:不要在意这个"设计"的创造者的想法,但我不能改变它.

这是关于MobileTansAuthenticators... 之间的关系

MobileTans表的各自映射:

@Entity
@Table(name="MobileTans")
public class MobileTan implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="ID", insertable=false, updatable=false)
    private Integer id;    // dupe read-only field, ID already in relationship below (writable)

    @Basic(optional=false)
    @Column(name="MOBILE_PHONE_NBR")
    private String mobilePhoneNbr;

    @Basic
    @Column(name="ACTIVATION_CODE")
    private String activationCode;

    @Basic
    @Column(name="ACTIVATION_ERROR")
    private Boolean activationError = Boolean.FALSE;

    @Basic
    @Column(name="STATUS")
    private Integer status;

    @OneToOne(optional=false, fetch=FetchType.EAGER)
    @JoinColumn(name="ID", referencedColumnName="ID")
    @JoinColumn(name="AUTH_NAME", referencedColumnName="AUTHENTICATOR")
    private Authenticator authenticator;

    ...
}
Run Code Online (Sandbox Code Playgroud)

这里的线索是列的重复只读映射(insertable=false, updatable=false)@Id.

ID列被定义为PK,因此在设置@Id关系时没有用处.我必须创建一个额外的列映射.我把只读只放在额外的列上,因为Hibernate(或JPA)不允许我只在关系的某些部分指定只读(我认为这是JPA规范禁止的).

编辑:身份验证实体

@Entity
@Table(name="Authenticators")
@IdClass(AuthenticatorPk.class)
public class Authenticator implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="ID")
    private Integer id;

    @Id
    @Column(name="AUTHENTICATOR")
    private String authenticator = "";

    @Basic(optional=false)
    @Column(name="PROCEDURE")
    private String procedure;

    @Temporal(TemporalType.DATE)
    @Basic
    @Column(name="VALID_FROM")
    private Date validFrom;

    @Temporal(TemporalType.DATE)
    @Basic
    @Column(name="VALID_TO")
    private Date validTo;

    public Authenticator()
    {
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

PK类:

public class AuthenticatorPk implements Serializable
{
    private static final long serialVersionUID = 1L;

    private Integer id;

    private String authenticator = "";

    public AuthenticatorPk()
    {
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

启动服务器时,我从Hibernate获取映射异常:

00:37:53,979 INFO  [org.hibernate.Version] (ServerService Thread Pool -- 72) HHH000412: Hibernate Core {5.3.6.Final}
00:37:53,980 INFO  [org.hibernate.cfg.Environment] (ServerService Thread Pool -- 72) HHH000206: hibernate.properties not found
00:37:54,088 INFO  [org.hibernate.annotations.common.Version] (ServerService Thread Pool -- 72) HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
00:37:54,382 INFO  [org.hibernate.validator.internal.util.Version] (MSC service thread 1-2) HV000001: Hibernate Validator 6.0.13.Final
00:37:54,621 INFO  [org.jboss.weld.Version] (MSC service thread 1-3) WELD-000900: 3.0.5 (Final)
00:37:54,674 INFO  [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 72) WFLYCLINF0002: Started client-mappings cache from ejb container
00:37:54,777 INFO  [org.jboss.as.jpa] (ServerService Thread Pool -- 72) WFLYJPA0010: Starting Persistence Unit (phase 2 of 2) Service 'mappingbug.war#BBStatsPU'
00:37:54,806 INFO  [org.hibernate.dialect.Dialect] (ServerService Thread Pool -- 72) HHH000400: Using dialect: org.hibernate.dialect.MySQL57Dialect
00:37:54,859 INFO  [org.hibernate.envers.boot.internal.EnversServiceImpl] (ServerService Thread Pool -- 72) Envers integration enabled? : true
00:37:55,007 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 72) MSC000001: Failed to start service jboss.persistenceunit."mappingbug.war#BBStatsPU": org.jboss.msc.service.StartException in service jboss.persistenceunit."mappingbug.war#BBStatsPU": javax.persistence.PersistenceException: [PersistenceUnit: BBStatsPU] Unable to build Hibernate SessionFactory
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:195)
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:125)
    at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:650)
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:209)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
    at java.lang.Thread.run(Thread.java:748)
    at org.jboss.threads.JBossThread.run(JBossThread.java:485)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: BBStatsPU] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1016)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:942)
    at org.jboss.as.jpa.hibernate5.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44)
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:167)
    ... 9 more
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: net.bbstats.entity.MobileTan column: ID (should be mapped with insert="false" update="false")
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:862)
    at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:880)
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:902)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:634)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:267)
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:347)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:466)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939)
    ... 11 more

00:37:55,011 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "mappingbug.war")]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.persistenceunit.\"mappingbug.war#BBStatsPU\"" => "javax.persistence.PersistenceException: [PersistenceUnit: BBStatsPU] Unable to build Hibernate SessionFactory
    Caused by: javax.persistence.PersistenceException: [PersistenceUnit: BBStatsPU] Unable to build Hibernate SessionFactory
    Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: net.bbstats.entity.MobileTan column: ID (should be mapped with insert=\"false\" update=\"false\")"}}
00:37:55,018 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 42) WFLYSRV0010: Deployed "mappingbug.war" (runtime-name : "mappingbug.war")
00:37:55,019 INFO  [org.jboss.as.controller] (Controller Boot Thread) WFLYCTL0183: Service status report
WFLYCTL0186:   Services which failed to start:      service jboss.persistenceunit."mappingbug.war#BBStatsPU": javax.persistence.PersistenceException: [PersistenceUnit: BBStatsPU] Unable to build Hibernate SessionFactory
WFLYCTL0448: 19 additional services are down due to their dependencies being missing or failed
00:37:55,079 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
00:37:55,081 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
00:37:55,081 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
00:37:55,082 ERROR [org.jboss.as] (Controller Boot Thread) WFLYSRV0026: WildFly Full 14.0.1.Final (WildFly Core 6.0.2.Final) started (with errors) in 14146ms - Started 449 of 645 services (23 services failed or missing dependencies, 328 services are lazy, passive or on-demand)
Run Code Online (Sandbox Code Playgroud)

顺便说一下,我在Wildfly 14上使用Hibernate Core 5.3.6.Final.

问题:

这有什么不对?为什么Hibernate抱怨这个?我的印象是,这是完全合法的.

其他机会是这是一个Hibernate错误......?

请注意,我更想知道这是否应该在Hibernate中工作.我对任何非JPA替代映射都不感兴趣.通过将只读的东西放到关系上,我可以得到这个,然后这可行,但不是上面描述的映射,应该......你得到它:-)