org.hibernate.MappingException: Unable to find column with logical name for ManyToOne association

1k Views Asked by At

Sorry to ask this question. Many may say that there are lots of answers but My bad luck none of those worked for me.

Here is the Entity Class: TIMELINE ENTITY:

@Entity
@Table(name = "TIMELINE")
public class Timeline extends ChronosEntity implements HasIdAndDomain, HasIdAndOwnerUser {
private Long id;
private String name;
private int nofAsgSlotsPerDay;
private Long ownerUserId;
private User owner;
private Long domainId;
private Domain domain;

@Id
@Column(name = "TIMELINE_ID", columnDefinition = "BIGINT(15)")
@GeneratedValue
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Column(name = "TIMELINE_NAME", unique = true)
@NotNull
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Column(name = "NOF_ASG_SLOTS_PER_DAY")
public int getNofAsgSlotsPerDay() {
    return nofAsgSlotsPerDay;
}

public void setNofAsgSlotsPerDay(int nofAsgSlotsPerDay) {
    this.nofAsgSlotsPerDay = nofAsgSlotsPerDay;
}

@Column(name = "OWNER_USER_ID")
public Long getOwnerUserId() {
    return ownerUserId;
}

public void setOwnerUserId(Long ownerUserId) {
    this.ownerUserId = ownerUserId;
}

@ManyToOne
@JoinColumn(name = "OWNER_USER_ID", referencedColumnName = "USER_ID", insertable = false, updatable = false)
public User getOwner() {
    return owner;
}

public void setOwner(User owner) {
    this.owner = owner;
}

@Column(name = "DOMAIN_ID")
public Long getDomainId() {
    return domainId;
}

public void setDomainId(Long domainId) {
    this.domainId = domainId;
}

@ManyToOne
@JoinColumn(name = "DOMAIN_ID", referencedColumnName = "DOMAIN_ID", insertable = false, updatable = false)
public Domain getDomain() {
    return domain;
}

public void setDomain(Domain domain) {
    this.domain = domain;
}
}

One this to mention is that I am not using bi-directional association. Domain entity has the primary key "DOMAIN_ID".

Now the error:

org.hibernate.MappingException: Unable to find column with logical name: TIMELINE_ID in org.hibernate.mapping.Table(DOMAIN) and its related supertables and secondary tables
at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:829)
at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:242)
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:100)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1757)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1700)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1628)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:276)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:770)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:797)
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:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:664)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:630)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:678)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:549)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:490)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1193)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1088)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3954)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
at java.lang.Thread.run(Thread.java:745)

Thanks in advance \n Edit-1: Domain Entity:

@Entity
@Table(name = "DOMAIN")
public class Domain extends ChronosEntity implements HasId, HasIdAndOwnerUser {
@Id
@Column(name = "DOMAIN_ID", columnDefinition = "BIGINT(15)")
@GeneratedValue
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Column(name = "DOMAIN_NAME", unique = true)
@NotNull
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Column(name = "OWNER_USER_ID")
public Long getOwnerUserId() {
    return ownerUserId;
}

public void setOwnerUserId(Long ownerUserId) {
    this.ownerUserId = ownerUserId;
}

@ManyToOne
@JoinColumn(name = "OWNER_USER_ID", referencedColumnName = "USER_ID", insertable = false, updatable = false, columnDefinition = "BIGINT(15)")
public User getOwner() {
    return owner;
}

@SuppressWarnings("unused")
private void setOwner(User owner) {
    this.owner = owner;
}

@Column(name = "CREATION_DATE")
@Temporal(value = TemporalType.TIMESTAMP)
@CreationTimestamp
public Date getCreationDate() {
    return creationDate;
}

public void setCreationDate(Date creationDate) {
    this.creationDate = creationDate;
}
}

Edit-2: Chronos entity.

@MappedSuperclass
public class ChronosEntity {
private Long version;
private Long transactionId;

@Version
@Column(name="VERSION", columnDefinition="BIGINT(15)")
public Long getVersion() {
    return version;
}
public void setVersion(Long version) {
    this.version = version;
}

@Column(name="TRANSACTION_ID", columnDefinition="BIGINT(15)")
public Long getTransactionId() {
    return transactionId;
}
public void setTransactionId(Long transactionId) {
    this.transactionId = transactionId;
}
}

Annotation from javax.persistence package.

1

There are 1 best solutions below

2
Avi On

You should also create the opposite @OneToMany association in the DOMAIN object. You can leave it a private field if you don't want the bi-directional association.

Add this to Domain class:

@OneToMany(mappedBy="domain")
private List<TimeLine> timelines =  new ArrayList<>();

According to the way you described the problem you do have bi-directional association, you just don't want things to be changed on the Timeline object when working on a Domain object so just make sure timelines is private and has no getter/setter. This will solve the problem and still keep the desired behavior.