I am modeling a database.
There is TRIPLE which contains three CONCEPT. So the primary key of the class TRIPLE is three uri all together. (One concept could be in different TRIPLE).
Also TRIPLE is related with another class, ANNOTATION, and here is the question, how can triple_id be identified?? But first of all, if building this Id composite is correct.
To model that:
Concept.java
#Entity
#Table(name = "concept")
public class Concept implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private List<TripleDBModel> triples;
#ManyToMany(
cascade={CascadeType.ALL},
fetch=FetchType.LAZY,
mappedBy = "concepts"
)
public List<TripleDBModel> getTriples() {
return triples;
}
public void setTriples(List<TripleDBModel> triples) {
this.triples = triples;
}
ConceptPk.java
#Embeddable
public class ConceptPk implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String uri;
public ConceptPk(String uri, String label){
this.uri = uri;
}
public ConceptPk(){
super();
}
#Id
#Column(name = "uri", length = 100, unique = true, nullable = false)
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
}
Triple.java
#Entity
#IdClass(ConceptPk.class)
#Table(name = "triple")
public class TripleDBModel {
protected List<Annotation> annotations;
protected String conceptUriSubject;
protected String conceptUriObject;
protected String conceptUriPredicate;
#ManyToMany(
cascade={CascadeType.ALL},
fetch=FetchType.LAZY
)
#JoinTable(name = "triple_has_concept",
joinColumns=#JoinColumn(name="uri"),
inverseJoinColumns=#JoinColumn(name="triple_id")) //What shoul I write here???
public List<Annotation> getAnnotations() {
return annotations;
}
public void setAnnotations(List<Annotation> annotations) {
this.annotations = annotations;
}
#Id public String getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(String conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
#Id public String getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(String conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
#Id public String getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(String conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
}
Thanks in advance!!
You could use an Id class like this:
class TripleId implements Serializable {
#Column(...)
private String conceptUriSubject;
#Column(...)
private String conceptUriObject;
}
And use it in Triple:
#Entity
#Table(name = "triple")
public class TripleDBModel {
#EmbeddedId
private TripleId id;
...
}
Also note that you can provide multiple join columns:
inverseJoinColumns= {#JoinColumn(name="subjectUri"), #JoinColumn(name="objectUri"), ... }
Related
These are my model classes:
Film.java
#Entity
public class Film {
private Integer id;
private String title;
private List<FilmActor> filmActors;
#OneToMany(mappedBy = "film")
public List<FilmActor> getFilmActors() {
return filmActors;
}
public void setFilmActors(List<FilmActor> filmActors) {
this.filmActors = filmActors;
}
}
Actor.java
#Entity
public class Actor {
private Integer id;
private String firstname;
private String lastname;
private List<FilmActor> filmActors;
#OneToMany(mappedBy = "actor")
public List<FilmActor> getFilmActors() {
return filmActors;
}
public void setFilmActors(List<FilmActor> filmActors) {
this.filmActors = filmActors;
}
}
And this is the Join Table Entity:
#Entity
#Table(name = "film_actor")
public class FilmActor {
private FilmActorPK id;
private Film film;
private Actor actor;
private Timestamp lastUpdate;
#EmbeddedId
public FilmActorPK getId() {
return id;
}
public void setId(FilmActorPK id) {
this.id = id;
}
#ManyToOne
#MapsId("film")
#JoinColumn(name = "film_id")
public Film getFilm() {
return film;
}
public void setFilm(Film film) {
this.film = film;
}
#ManyToOne
#MapsId("actor")
#JoinColumn(name = "actor_id")
public Actor getActor() {
return actor;
}
public void setActor(Actor actor) {
this.actor = actor;
}
#Column(name = "last_update")
public Timestamp getLastUpdate() {
return lastUpdate;
}
public void setLastUpdate(Timestamp lastUpdate) {
this.lastUpdate = lastUpdate;
}
}
and the Primary Key class:
#Embeddable
public class FilmActorPK implements Serializable {
private int actorId;
private int filmId;
#Column(name = "actor_id")
public int getActorId() {
return actorId;
}
public void setActorId(int actorId) {
this.actorId = actorId;
}
#Column(name = "film_id")
public int getFilmId() {
return filmId;
}
public void setFilmId(int filmId) {
this.filmId = filmId;
}
}
So I want to find films where 2 given actors acts. This is what I have:
#Override
public Collection<Film> filmsActorsTogether(Actor a, Actor b) {
final List<Film> filmsOfActorA = filmsOfActor(a);
final List<Film> filmsOfActorB = filmsOfActor(b);
final Collection<Film> intersection = CollectionUtils.intersection(filmsOfActorA, filmsOfActorB);
return intersection;
}
#Override
public List<Film> filmsOfActor(Actor actor) {
final EntityManager entityManager = persistenceUtil.getEntityManager();
final Actor persistentActor = entityManager.find(Actor.class, actor.getId());
final ArrayList<Film> films = new ArrayList<Film>();
for (FilmActor filmActor : persistentActor.getFilmActors()) {
films.add(filmActor.getFilm());
}
entityManager.close();
return films;
}
Is there any way to achieve this without fetching ALL films of 2 actors, and using filtering in memory? How do I get the Films directly from the DB with JQL?
Maybe there is something more elegant, but the following query should work:
select f from Film f where
(select count(fa.id) from FilmActor fa
where fa.film = f
and (fa.actor = :actor1 or fa.actor = :actor2)) = 2
Side note: your PK class should have a correct equals() and hashCode() methods
I want to make a table, let's say table's name is Car. It will has 3 column, brandId, typeId and sizeId. I want all of the columns to be primary key. typeId and sizeId are column from different table. I already try to make code using #IdClass. But, error "No supertype found" appear.
This is Entity clas :
#Entity
#IdClass(CarPk.class)
#Table(name = "CAR")
public class Car implements Serializable {
private static final long serialVersionUID = -1576946068763487642L;
public Car() {
}
public Car(String brandId, TypeId typeId, SizeId sizeId) {
this.brandId = brandId;
this.typeId = typeId;
this.sizeId = sizeId;
}
#Id
#Column(name = "BRAND_ID", nullable = false, length = 20)
private String brandId;
#Id
#ManyToOne
#JoinColumn(name = "TYPE_ID", nullable = false)
private TypeId typeId;
#Id
#ManyToOne
#JoinColumn(name = "SIZE_ID", nullable = false)
private SizeId sizeId;
public String getBrandId() {
return brandId;
}
public void setBrandId(String brandId) {
this.brandId= brandId;
}
public TypeId getTypeId() {
return typeId;
}
public void setTypeId (TypeId typeId) {
this.typeId= typeId;
}
public SizeId getSizeId() {
return sizeId;
}
public void setSizeId (SizeId sizeId) {
this.sizeId= sizeId;
}
}
And this is CarPk class :
public class CarPk implements Serializable {
private static final long serialVersionUID = -1576946068763487642L;
public CarPk() {
}
public CarPk(String brandId, TypeId typeId, SizeId sizeId) {
this.brandId = brandId;
this.typeId = typeId;
this.sizeId = sizeId;
}
private String brandId;
private TypeId typeId;
private SizeId sizeId;
public String getBrandId() {
return brandId;
}
public void setBrandId(String brandId) {
this.brandId= brandId;
}
public TypeId getTypeId() {
return typeId;
}
public void setTypeId (TypeId typeId) {
this.typeId= typeId;
}
public SizeId getSizeId() {
return sizeId;
}
public void setSizeId (SizeId sizeId) {
this.sizeId= sizeId;
}
}
What is wrong this code?
Thank you anyway
I have two entities that related with One to Many connection. One is Path another is Point, one path can have few points. And I have view on MySQL side that joined those tables using join table. I need to get the result of query to that view. Here is first
#Entity
#Table(name = "paths")
public class Path {
#JsonIgnore
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.AUTO)
private Long pathID;
#Column(name="path_name")
private String pathName;
#Column(name="path_type")
private Long pathType;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="uid")
#JsonIgnore
private User owner;
#Column(name="path_status")
private Long pathStatus;
#Column(name="description")
private String pathDescription;
#Column(name="created")
private Long created;
#OneToMany(mappedBy = "primaryKey.point", cascade = CascadeType.ALL)
private Set<PathPoints> pathPoints = new HashSet<PathPoints>();
public Long getPathID(){
return this.pathID;
}
public void setPathID(Long pathID){
this.pathID = pathID;
}
public String getPathName(){
return this.pathName;
}
public void setPathName(String pathName){
this.pathName = pathName;
}
public Long getPathType(){
return this.pathType;
}
public void setPathType(Long pathType){
this.pathType = pathType;
}
public Long getPathStatus(){
return this.pathStatus;
}
public void setPathStatus(Long pathStatus){
this.pathStatus = pathStatus;
}
public String getPathDescription(){
return this.pathDescription;
}
public void setPathDescription(String pathDescription){
this.pathDescription = pathDescription;
}
public Long getCreated(){
return this.created;
}
public void setCreated(Long created){
this.created = created;
}
public Set<PathPoints> getPathPoints() {
return pathPoints;
}
public void setPathPoints(Set<PathPoints> pathPoints) {
this.pathPoints = pathPoints;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
Here is second
#Entity
#Table(name = "path_points")
#AssociationOverrides({
#AssociationOverride(name = "primaryKey.point", joinColumns = #JoinColumn(name = "point_id")),
#AssociationOverride(name = "primaryKey.path", joinColumns = #JoinColumn(name = "path_id"))
})
public class PathPoints{
private PathPointID primaryKey = new PathPointID();
private Long endTime;
private Long startTime;
#Column(name="end_time")
public Long getEndTime() {
return endTime;
}
public void setEndTime(Long endTime) {
this.endTime = endTime;
}
#Column(name="start_time")
public Long getStartTime() {
return startTime;
}
public void setStartTime(Long startTime) {
this.startTime = startTime;
}
#JsonIgnore
#EmbeddedId
public PathPointID getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(PathPointID primaryKey) {
this.primaryKey = primaryKey;
}
#Transient
public Point getPoint() {
return primaryKey.getPoint();
}
public void setPoint(Point point) {
this.primaryKey.setPoint(point);;
}
#JsonIgnore
#Transient
public Path getPath() {
return primaryKey.getPath();
}
public void setPath(Path path) {
this.primaryKey.setPath(path);;
}
}
And that is ID class
#Embeddable
public class PathPointID implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Point point;
private Path path;
#ManyToOne(cascade = CascadeType.ALL)
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
#ManyToOne(cascade = CascadeType.ALL)
public Path getPath() {
return path;
}
public void setPath(Path path) {
this.path = path;
}
}
You need to create third entity class and make jpa/hibernate operations with it.
#Entity
#Table(name = "your_view_name")
public class YourView {
#Column(name="someColumnFromYourView")
private String someColumnFromYourView;
#Transient
private List<Point> points;
...
}
and then do
YourView view = ...//get this view data by some parameters
view.setPoints(yourDaoMethodToGetPoints(view));
you can see this example. I'm using PostgreSQL and JPA 2.1 here.I wrote a view on the database and mapped it to JPA entity.There one thing you need to remember - you cannot do write operations on this view.
I'm trying implement a rest service. I have created my entitys and daos, and when use this everthyng works fine.
But when I trye expose the information in rest json, the infinite recursion error occur.
I have read many topic about this error, but not is so clear for me.
I'm have tried so many alternatives that is hard talk about each.
When I debug my code, I see that the data from dao is correctly, the problem occur when I trie use json. Whe I use jsf page works fine.
I have tried use Gson and return String in my rest method, but stackoverflow error occur to.
Bellow I post my implememtation (all), because a dont have idea about the problem.
I using wildfly server...
Thanks in advance
Model's
#Entity
#Table(name="usertable")
#NamedQuery(name="UserModel.findAll", query="SELECT u FROM UserModel u")
#XmlRootElement
public class UserModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private String USId;
#Temporal(TemporalType.DATE)
#Column(nullable=false)
private Date userNascimento;
#Column(nullable=false, length=45)
private String USMail;
#Column(nullable=false, length=150)
private String USName;
#Column(nullable=false, length=45)
private String USNick;
#Column(nullable=false, length=45)
private String USPassword;
//bi-directional many-to-one association to UserAddressModel
#OneToMany(fetch = FetchType.EAGER, mappedBy="usertable")
private List<UserAddressModel> listAddressModel;
//bi-directional many-to-one association to UserFoneModel
#OneToMany(fetch = FetchType.EAGER, mappedBy="usertable")
private List<UserFoneModel> listFoneModel;
public UserModel() {
}
public String getUSId() {
return this.USId;
}
public void setUSId(String USId) {
this.USId = USId;
}
public Date getUserNascimento() {
return this.userNascimento;
}
public void setUserNascimento(Date userNascimento) {
this.userNascimento = userNascimento;
}
public String getUSMail() {
return this.USMail;
}
public void setUSMail(String USMail) {
this.USMail = USMail;
}
public String getUSName() {
return this.USName;
}
public void setUSName(String USName) {
this.USName = USName;
}
public String getUSNick() {
return this.USNick;
}
public void setUSNick(String USNick) {
this.USNick = USNick;
}
public String getUSPassword() {
return this.USPassword;
}
public void setUSPassword(String USPassword) {
this.USPassword = USPassword;
}
public List<UserAddressModel> getUseraddresstables() {
return this.listAddressModel;
}
public void setUseraddresstables(List<UserAddressModel> useraddresstables) {
this.listAddressModel = useraddresstables;
}
public UserAddressModel addUseraddresstable(UserAddressModel useraddresstable) {
getUseraddresstables().add(useraddresstable);
useraddresstable.setUsertable(this);
return useraddresstable;
}
public UserAddressModel removeUseraddresstable(UserAddressModel useraddresstable) {
getUseraddresstables().remove(useraddresstable);
useraddresstable.setUsertable(null);
return useraddresstable;
}
public List<UserFoneModel> getUserfonetables() {
return this.listFoneModel;
}
public void setUserfonetables(List<UserFoneModel> userfonetables) {
this.listFoneModel = userfonetables;
}
public UserFoneModel addUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().add(userfonetable);
userfonetable.setUsertable(this);
return userfonetable;
}
public UserFoneModel removeUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().remove(userfonetable);
userfonetable.setUsertable(null);
return userfonetable;
}
}
#Entity
#Table(name="userfonetable")
#NamedQuery(name="UserFoneModel.findAll", query="SELECT u FROM UserFoneModel u")
public class UserFoneModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private String UFId;
#Column(nullable=false)
private short UFDdd;
#Column(nullable=false)
private int UFFone;
//bi-directional many-to-one association to UserModel
#ManyToOne
#JoinColumn(name="UFUserID", nullable=false)
private UserModel usertable;
//bi-directional many-to-one association to OperadorasModel
#ManyToOne
#JoinColumn(name="UFOperadoraID", nullable=false)
private OperadorasModel operadorastable;
//bi-directional many-to-one association to TiposFoneModel
#ManyToOne
#JoinColumn(name="UFTipoTelefone", nullable=false)
private TiposFoneModel tbTipostelefone;
public UserFoneModel() {
}
public String getUFId() {
return this.UFId;
}
public void setUFId(String UFId) {
this.UFId = UFId;
}
public short getUFDdd() {
return this.UFDdd;
}
public void setUFDdd(short UFDdd) {
this.UFDdd = UFDdd;
}
public int getUFFone() {
return this.UFFone;
}
public void setUFFone(int UFFone) {
this.UFFone = UFFone;
}
public UserModel getUsertable() {
return this.usertable;
}
public void setUsertable(UserModel usertable) {
this.usertable = usertable;
}
public OperadorasModel getOperadorastable() {
return this.operadorastable;
}
public void setOperadorastable(OperadorasModel operadorastable) {
this.operadorastable = operadorastable;
}
public TiposFoneModel getTbTipostelefone() {
return this.tbTipostelefone;
}
public void setTbTipostelefone(TiposFoneModel tbTipostelefone) {
this.tbTipostelefone = tbTipostelefone;
}
}
#Entity
#Table(name="useraddresstable")
#NamedQuery(name="UserAddressModel.findAll", query="SELECT u FROM UserAddressModel u")
public class UserAddressModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private String UAId;
#Column(nullable=false, length=100)
private String UABairro;
#Column(nullable=false, length=100)
private String UACidade;
#Column(length=45)
private String UAComplemento;
#Column(nullable=false, length=2)
private String UAEstado;
#Column(nullable=false)
private int UANumero;
#Column(length=100)
private String UARua;
//bi-directional many-to-one association to UserModel
#ManyToOne
#JoinColumn(name="UAUserID", nullable=false)
private UserModel usertable;
public UserAddressModel() {
}
public String getUAId() {
return this.UAId;
}
public void setUAId(String UAId) {
this.UAId = UAId;
}
public String getUABairro() {
return this.UABairro;
}
public void setUABairro(String UABairro) {
this.UABairro = UABairro;
}
public String getUACidade() {
return this.UACidade;
}
public void setUACidade(String UACidade) {
this.UACidade = UACidade;
}
public String getUAComplemento() {
return this.UAComplemento;
}
public void setUAComplemento(String UAComplemento) {
this.UAComplemento = UAComplemento;
}
public String getUAEstado() {
return this.UAEstado;
}
public void setUAEstado(String UAEstado) {
this.UAEstado = UAEstado;
}
public int getUANumero() {
return this.UANumero;
}
public void setUANumero(int UANumero) {
this.UANumero = UANumero;
}
public String getUARua() {
return this.UARua;
}
public void setUARua(String UARua) {
this.UARua = UARua;
}
public UserModel getUsertable() {
return this.usertable;
}
public void setUsertable(UserModel usertable) {
this.usertable = usertable;
}
}
#Entity
#Table(name="tb_tipostelefone")
#NamedQuery(name="TiposFoneModel.findAll", query="SELECT t FROM TiposFoneModel t")
public class TiposFoneModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private short TFId;
#Column(nullable=false, length=45)
private String TFDescricao;
//bi-directional many-to-one association to UserFoneModel
#OneToMany(fetch = FetchType.EAGER, mappedBy="tbTipostelefone")
private List<UserFoneModel> listFoneModel;
public TiposFoneModel() {
}
public short getTFId() {
return this.TFId;
}
public void setTFId(short TFId) {
this.TFId = TFId;
}
public String getTFDescricao() {
return this.TFDescricao;
}
public void setTFDescricao(String TFDescricao) {
this.TFDescricao = TFDescricao;
}
public List<UserFoneModel> getUserfonetables() {
return this.listFoneModel;
}
public void setUserfonetables(List<UserFoneModel> userfonetables) {
this.listFoneModel = userfonetables;
}
public UserFoneModel addUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().add(userfonetable);
userfonetable.setTbTipostelefone(this);
return userfonetable;
}
public UserFoneModel removeUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().remove(userfonetable);
userfonetable.setTbTipostelefone(null);
return userfonetable;
}
}
#Entity
#Table(name="operadorastable")
#NamedQuery(name="OperadorasModel.findAll", query="SELECT o FROM OperadorasModel o")
public class OperadorasModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private short OPCodigo;
#Column(nullable=false, length=100)
private String opNome;
//bi-directional many-to-one association to UserFoneModel
#OneToMany(fetch = FetchType.EAGER, mappedBy="operadorastable")
private List<UserFoneModel> listFoneModel;
public OperadorasModel() {
}
public short getOPCodigo() {
return this.OPCodigo;
}
public void setOPCodigo(short OPCodigo) {
this.OPCodigo = OPCodigo;
}
public String getOpNome() {
return this.opNome;
}
public void setOpNome(String opNome) {
this.opNome = opNome;
}
public List<UserFoneModel> getUserfonetables() {
return this.listFoneModel;
}
public void setUserfonetables(List<UserFoneModel> userfonetables) {
this.listFoneModel = userfonetables;
}
public UserFoneModel addUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().add(userfonetable);
userfonetable.setOperadorastable(this);
return userfonetable;
}
public UserFoneModel removeUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().remove(userfonetable);
userfonetable.setOperadorastable(null);
return userfonetable;
}
}
DAO
#Stateless
#LocalBean
public class UserDao {
/**
* Default constructor.
*/
#PersistenceContext
EntityManager em;
public UserDao() {
// TODO Auto-generated constructor stub
}
public List<UserModel> listAll()
{
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<UserModel> cq = cb.createQuery(UserModel.class);
Root<UserModel> rootEntry = cq.from(UserModel.class);
CriteriaQuery<UserModel> all = cq.select(rootEntry);
TypedQuery<UserModel> allQuery = em.createQuery(all);
List<UserModel> listU = allQuery.getResultList();
return listU;
/*
Query query = em.createQuery("SELECT u FROM UserModel u");
return query.getResultList();
*/
}
}
My Rest
import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import br.com.avera.dao.UserDao;
import br.com.avera.model.UserAddressModel;
import br.com.avera.model.UserFoneModel;
import br.com.avera.model.UserModel;
#Path("/users")
public class UserRest {
#Inject
UserDao userDao;
#GET
#Produces(MediaType.APPLICATION_JSON)
public UserModel getUser()
{
List<UserModel> userModelList = userDao.listAll();
UserModel userModel = userModelList.get(0);
List<UserFoneModel> lFone = userModel.getUserfonetables();
for (UserFoneModel userFoneModel : lFone) {
System.out.println(userFoneModel.getUFDdd());
System.out.println(userFoneModel.getUFFone());
}
System.out.println("OOOOOO");
List<UserAddressModel> lAddressModels = userModel.getUseraddresstables();
for (UserAddressModel userAddressModel : lAddressModels) {
System.out.println(userAddressModel.getUACidade());
System.out.println(userAddressModel.getUAEstado());
}
return userModel;
}
}
Although I made a little research on this, and I found a lot of threats opened in Internet, I couldn't solve my problem. I attach my code:
Triple.java the primary key is made by 3 URIs from three different concepts, but it is the same column (is it a problem?)
#Entity
#IdClass(ConceptPk.class)
#Table(name = "triple")
public class TripleDBModel {
protected List<Annotation> annotations;
public String conceptUriSubject;
public String conceptUriObject;
public String conceptUriPredicate;
public String id;
#ManyToMany(
cascade={CascadeType.ALL},
fetch=FetchType.LAZY
)
#JoinTable(name = "triple_has_annotation",
joinColumns=#JoinColumn(name="annotation_id"),
inverseJoinColumns={#JoinColumn(name="uri_concept_subject", referencedColumnName="triple_id"), #JoinColumn(name="uri_concept_object", referencedColumnName="triple_id"), #JoinColumn(name="uri_concept_predicate", referencedColumnName="triple_id")
})//EDIT
public List<Annotation> getAnnotations() {
return annotations;
}
public void setAnnotations(List<Annotation> annotations) {
this.annotations = annotations;
}
#Id
#Column(name = "uri_concept_subject", length = 100)
public String getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(String conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
#Id
#Column(name = "uri_concept_object", length = 100)
public String getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(String conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
#Id
#Column(name = "uri_concept_predicate", length = 100)
public String getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(String conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
#Id
#Column(name = "triple_id", unique = true, nullable = false)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
ConceptPk.java
#Embeddable
public class ConceptPk implements java.io.Serializable {
private static final long serialVersionUID = 1L;
public String conceptUriSubject;
public String conceptUriObject;
public String conceptUriPredicate;
#Id
#Column(name = "uri", length = 100, unique = true, nullable = false)
public String getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(String conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
#Id
#Column(name = "uri", length = 100, unique = true, nullable = false)
public String getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(String conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
#Id
#Column(name = "uri", length = 100, unique = true, nullable = false)
public String getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(String conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
Annotation.java
#Entity
#Table(name = "annotations")
public class Annotation {
private Integer id;
private List<TripleDBModel> triples;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "annotation_id", unique = true, nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#ManyToMany(
cascade={CascadeType.ALL},
mappedBy = "annotations", //EDIT
fetch=FetchType.LAZY
)
public List<TripleDBModel> getTriples() {
return triples;
}
public void setTriples(List<TripleDBModel> triples) {
this.triples = triples;
}
But I am getting this error:
Caused by: org.hibernate.AnnotationException: A Foreign key refering TripleDBModel from Annotation has the wrong number of column. should be 3
What am I doing wrong?? Thanks in advance
The final solution is:
ConceptPk.java
#Embeddable
public class ConceptPk implements java.io.Serializable {
private static final long serialVersionUID = 1L;
public Concept conceptUriSubject;
public Concept conceptUriObject;
public Concept conceptUriPredicate;
#Id
#ManyToOne(cascade=CascadeType.MERGE)
#JoinColumn(name="uri_concept_subject")
public Concept getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(Concept conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
#Id
#ManyToOne(cascade=CascadeType.MERGE)
#JoinColumn(name="uri_concept_object")
public Concept getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(Concept conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
#Id
#ManyToOne(cascade=CascadeType.MERGE)
#JoinColumn(name="uri_concept_predicate")
public Concept getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(Concept conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
Triple.java
#Entity
#IdClass(ConceptPk.class)
#Table(name = "triple")
public class TripleDBModel {
protected List<Annotation> annotations;
public Concept conceptUriSubject;
public Concept conceptUriObject;
public Concept conceptUriPredicate;
#ManyToMany(
cascade={CascadeType.ALL },
fetch=FetchType.LAZY
)
#JoinTable(name = "triple_has_annotation",
joinColumns={#JoinColumn(name="uri_concept_subject"), #JoinColumn(name="uri_concept_object"), #JoinColumn(name="uri_concept_predicate") },
inverseJoinColumns=#JoinColumn(name="annotation_id") )
public List<Annotation> getAnnotations() {
return annotations;
}
public void setAnnotations(List<Annotation> annotations) {
this.annotations = annotations;
}
#Id
#Column(name = "uri_concept_subject", length = 100)
public Concept getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(Concept conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
#Id
#Column(name = "uri_concept_object", length = 100)
public Concept getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(Concept conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
#Id
#Column(name = "uri_concept_predicate", length = 100)
public Concept getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(Concept conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
}
I'm not sure this is the cause of the error message you get, but your mapping has several errors:
Each of the #JoinColumn in your inverseJoinColumns attribute should have their referencedColumnName attribute specified.
The values of the joinColumns and inverseJoinColumns attributes should be switched. joinColumns is used to reference the source entity. inverseJoinColumns is used to reference the target entity.
The mappedBy attribute should be annotations, and not annotation
(unrelated, but probably incorrect) : cascade=CascadeType.ALL is probably not what you want on a many-to-many. You don't want to delete all the annotations of a triple when this triple is deleted, since these annotations are referenced by other triples.
#ManyToMany(
cascade={CascadeType.ALL},
mappedBy = "annotation",
fetch=FetchType.LAZY
)
public List<TripleDBModel> getTriples() {
return triples;
}
The mappedBy should be "annotations"
Edit: Have a look at this wikibook, especially the bottom section. This is a quite good reference for association mappings etc.