1

Hi I have a two tables like below .

1) Task - id,name 2) Resource - id,name,defaultTask(foreign key to Task.id)

The mapping is one to Many - one task can have many resource.

The code for Task is like below.

@Entity
public class Task implements Serializable {
private long m_id;
private String m_name;

@Id
@GeneratedValue(
    strategy = GenerationType.AUTO
)
public long getId() {
    return this.m_id;
}

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

public String getName() {
    return this.m_name;
}

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

@OneToMany
@JoinColumn(
    name = "defaultTask"
)
private List<Resource> m_relatedResources;

public List<Resource> getrelatedResources() {
    return m_relatedResources;
}


public void setrelatedResources(List<Resource> relatedResources) {
    m_relatedResources = relatedResources;
}

And the code for Resource class is like below.

@Entity
public class Resource implements Serializable {
private Long m_id;
private String m_name;
@Id
@GeneratedValue(
    strategy = GenerationType.AUTO
)
public Long getId() {
    return this.m_id;
}

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

public String getName() {
    return this.m_name;
}

public void setName(String name) {
    this.m_name = name;
}
Task m_task;
@ManyToOne
@JoinColumn(
    name = "defaultTask"
)
public Task getTask() {
    return this.m_task;
}

public void setTask(Task task) {
    this.m_task = task;
}

}

When i execute it I am getting an error like

Initial SessionFactory creation failed.org.hibernate.MappingException: Could not determine type for: java.util.List, for columns: [org.hibernate.mapping.Column(relatedResources)]

What have i done wrong ?How can i fix the problem ?

Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
robin
  • 1,893
  • 1
  • 18
  • 38

4 Answers4

5

You can't apply annotations to methods or fields randomly. Normally, you should apply your annotations the same way as @Id..

In Task class OneToMany should be like

@OneToMany
@JoinColumn(
    name = "defaultTask"
)
public List<Resource> getrelatedResources() {
    return m_relatedResources;
}

Field access strategy (determined by @Id annotation). Put any JPA related annotation right above each method instead of field / property as for your id it is above method and it will get you away form exception.
Also there appears to be an issue with your bidrectional mapping metntioned by @PredragMaric so you need to use MappedBy which signals hibernate that the key for the relationship is on the other side. Click for a really good question on Mapped by.

Community
  • 1
  • 1
Viraj Nalawade
  • 3,137
  • 3
  • 28
  • 44
3

You're mixing annotating fields and getters in the same entity, you should move your @OneToMany to a getter

@OneToMany
@JoinColumn(mappedBy = "task")
public List<Resource> getrelatedResources() {
    return m_relatedResources;
}

and yes, as the others mentioned, it should be mappedBy = "task". I'll upvote this teamwork :)

Master Slave
  • 27,771
  • 4
  • 57
  • 55
3

Many mistakes here:

  1. you're annotating fields sometimes, and getters sometimes. Half of the annotation will be ignored: you must be consistent. It's one or the other.
  2. You're not respecting the Java Bean naming conventions. The getter must be getRelatedResources(), not getrelatedResources().
  3. A bidirectional association must have an owner side and an inverse side. In a OneToMany, the One is always the inverse side. The mapping should thus be:

.

@ManyToOne
@JoinColumn(name = "defaultTask")
public Task getTask() {
    return this.m_task;
}

and

@OneToMany(mappedBy = "task")
public List<Resource> getRelatedResources() {
    return m_relatedResources;
}

I also strongly advise you to respect the Java naming conventions. Variables should be named id and name, not m_id and m_name. This is especially important if you choose to annotate fields.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
2

@JoinColumn is only used on owner's side of the relation, ToOne side, which is Resource#task in your case. On the other side you should use mappedBy attribute to specify bidirectional relation. Change your Task#relatedResources mapping to this

@OneToMany(mappedBy = "task")
private List<Resource> m_relatedResources;

Also, as @Viraj Nalawade noticed (and others, obviously), mapping annotations should be on fields or properties, whatever is used for @Id takes precedence. Either move @Id to field, or move @OneToMany to getter.

Predrag Maric
  • 23,938
  • 5
  • 52
  • 68