0

I'm not understanding how to do something that is probably very easy to do. I have a table named "Composer". A "Composer" can have many compositions ("Composition" table). I get the following error when I run this through Spring Boot:

19:11:40 web.1  | Caused by: org.hibernate.AnnotationException: 
mappedBy reference an unknown target entity property: 
com.zack.music.domain.Composition.composition in com.zack.music.domain.Composer.compositions

Below are my entity classes. What am I doing wrong here?

package com.zack.music.domain;

import javax.persistence.*;
import java.io.Serializable;
import java.sql.Date;
import java.util.*;

@Entity
public class Composer implements Serializable {

    @Id
    private String name;

    private Date birth;
    private Date death;

    @OneToMany(mappedBy="composition")
    private List<Composition> compositions;

    protected Composer() { }

    public Composer(String name, Date birth, Date death) {
        this.name = name;
        this.birth = birth;
        this.death = death;
    }

    public String getName() {
        return name;
    }

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

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Date getDeath() {
        return death;
    }

    public void setDeath(Date death) {
        this.death = death;
    }

    public List<Composition> getCompositions() {
        return compositions;
    }

    public void setCompositions(List<Composition> compositions) {
        this.compositions = compositions;
    }
}

@Entity
public class Composition implements Serializable {

    @Id
    @Column(nullable = false)
    private String name;

    @ManyToOne  
    private Composer composer;

    protected Composition() { }

    public Composition(String name, Composer composer) {
        this.name = name;
        this.composer = composer;
    }

    public String getName() {
        return name;
    }

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

    public Composer getComposer() {
        return composer;
    }

    public void setComposer(Composer composer) {
        this.composer = composer;
    }
}
Zack Macomber
  • 6,682
  • 14
  • 57
  • 104
  • From your comments on your answer below you seem to be struggling with lazily loaded collections that Jackson is trying to serialize into JSON. Have a look at this basic Hibernate tutorial that I wrote [here](http://stackoverflow.com/q/24257449/2357233) – JamesENL Oct 23 '14 at 03:49

2 Answers2

0

mappedBy is telling hibernate the property name on the related entity that owns the relationship. There is no property named 'composition' on the related entity: Composition. You probably just meant for the value of mappedBy to be "composer".

Affe
  • 47,174
  • 11
  • 83
  • 83
  • That helped me get it running but now I get this error when I attempt to access Composer through my RestController: – Zack Macomber Oct 22 '14 at 23:30
  • 19:27:35 web.1 | 2014-10-22 19:27:35.283 ERROR 51088 --- [ qtp32696411-21] o.h. engine.jdbc.spi.SqlExceptionHelper : Unknown column 'compositio0_.composer_nam e' in 'field list' – Zack Macomber Oct 22 '14 at 23:31
  • Not to my knowledge. I'm rebuilding this with 'mvn clean package' and executing it locally with heroku foreman – Zack Macomber Oct 22 '14 at 23:34
  • This is what comes back from my RestController...Wed Oct 22 19:32:48 EDT 2014 There was an unexpected error (type=Internal Server Error, status=500). Could not write JSON: could not extract ResultSet (through reference chain: java.util.ArrayList[0]->com.zack.music.domain.Composer["compositions"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not extract ResultSet (through reference chain: java.util.ArrayList[0]->com.zack.music.domain.Composer["compositions"]) – Zack Macomber Oct 22 '14 at 23:35
0

I was able to solve it using @ElementCollection. Java Persistence/ElementCollection helped me figure it out. I also filled in the "name" attributes on all of my tables and columns which I think helped identify everything. Here are the updated entities that are working:

package com.zack.music.domain;

import javax.persistence.*;
import java.io.Serializable;
import java.sql.Date;
import java.util.*;

@Entity(name="COMPOSER")
public class Composer implements Serializable {

    @Id
    @Column(name="NAME", nullable = false)
    private String name;

    @Column(name="BIRTH", nullable = false)
    private Date birth;

    @Column(name="DEATH", nullable = true)
    private Date death;

    @ElementCollection
    @CollectionTable(
            name="COMPOSITION",
            joinColumns=@JoinColumn(name="COMPOSER", referencedColumnName="NAME")
    )
    @Column(name="NAME")
    private List<String> compositions;

    protected Composer() { }

    public Composer(String name, Date birth, Date death) {
        this.name = name;
        this.birth = birth;
        this.death = death;
    }

    public String getName() {
        return name;
    }

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

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Date getDeath() {
        return death;
    }

    public void setDeath(Date death) {
        this.death = death;
    }

    public List<String> getCompositions() {
        return compositions;
    }
}

@Entity(name="COMPOSITION")
public class Composition implements Serializable {

    @Id
    @Column(name="NAME", nullable = false)
    private String name;

    @Column(name="COMPOSER", nullable = false)
    private String composer;

    protected Composition() { }

    public Composition(String name, String composer) {
        this.name = name;
        this.composer = composer;
    }

    public String getName() {
        return name;
    }

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

    public String getComposer() {
        return composer;
    }

    public void setComposer(String composer) {
        this.composer = composer;
    }
}
Zack Macomber
  • 6,682
  • 14
  • 57
  • 104