问题
I have the following files in Play Framework 2.2.3
Controller:
public class Comment extends Controller
{
public Result create(UUID id)
{
models.blog.Blog blog = models.blog.Blog.finder.byId(id);
Result result;
if(blog == null)
{
result = notFound(main.render("404", error404.render()));
}
else
{
Form<models.blog.Comment> commentForm = Form.form(models.blog.Comment.class);
commentForm = commentForm.bindFromRequest();
if(commentForm.hasErrors())
{
result = badRequest(Json.toJson(commentForm));
}
else
{
models.blog.Comment comment = commentForm.get();
comment.setId(UUID.randomUUID());
comment.setTimeCreated(new Date());
comment.setBlogId(blog.getId());
comment.save();
result = ok(Json.toJson(comment));
}
}
return result;
}
}
And two models
@Entity
@Table(name="blog")
public class Blog extends Model
{
private static final SimpleDateFormat MONTH_LITERAL = new SimpleDateFormat("MMMMM"),
DAY_NUMBER = new SimpleDateFormat("d"),
YEAR_NUMBER = new SimpleDateFormat("yyyy");
public static Finder<UUID, Blog> finder = new Finder<UUID, Blog>(UUID.class, Blog.class);
@Id
@Column(name="id",length=36, nullable=false)
public UUID id;
@OneToOne
@JoinColumn(name="author_id")
public User author;
@Column(name="title",length=255)
public String title;
@Column(name="summary",length=255)
public String summary;
@Column(name="url",length=255)
public String url;
@Column(name="content")
public String content;
@Column(name="time_updated")
public Date time_created;
@Column(name="time_created", nullable=false)
public Date time_updated;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name="blog_id")
public List<Comment> comments;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name="blog_tag_map",
joinColumns={ @JoinColumn(name="blog_id", referencedColumnName="id") },
inverseJoinColumns={ @JoinColumn(name="tag_id", referencedColumnName="id") }
)
public List<Tag> tags;
public List<Comment> getComments()
{
return this.comments;
}
}
@Entity
@Table(name="blog_comment")
public class Comment extends Model
{
private static final SimpleDateFormat MONTH_LITERAL = new SimpleDateFormat("MMMMM"),
DAY_NUMBER = new SimpleDateFormat("d"),
YEAR_NUMBER = new SimpleDateFormat("yyyy");
@Id
@Column(name="id",length=36, nullable=false)
public UUID id;
@Column(name="blog_id", length=36)
public UUID blog_id;
@ManyToOne
public Blog blog;
@Column(name="content", length=500)
public String content;
@Column(name="website", length=255)
public String website;
@Column(name="name", length=255)
public String name;
@Column(name="time_created", updatable=false)
public Date time_created;
}
I have excluded some setters and getters from these models for brevity, so it doesn't clog up this post.
When I attempt to make a POST request to the aforementioned controller, everything goes fine until I get to the "comment.save()" statement in the controller file, then I get the following error.
I'm unsure why this save isn't going through, and why there is a column conflict. Help much appreciated
回答1:
The issue lies in the fact that you have defined basically two foreign key columns for Blog in your Comment's entity:
@Column(name = "blog_id", length = 36)
public UUID blog_id;
@ManyToOne
public Blog blog;
The default column name for your 'blog' field is: blog_id However, you've already named your 'blog_id' column that. Interestingly, no error/warning is thrown when creating this table...
So when you call comment.save(), the following insert statement is generated:
insert into blog_comment (id, blog_id, content, website, name, time_created, blog_id) values (?,?,?,?,?,?,?)
Notice a reference to 'blog_id' column twice, which is invalid. And this is because of the above double mapping.
To fix, just give your 'blog' property a different name to use for the foreign key column:
@Column(name = "blog_id", length = 36)
public UUID blog_id;
@ManyToOne
@JoinColumn(name = "blogId")
public Blog blog;
I'm not sure why you're mapping your entities like this (perhaps legacy schema?) but the 'blog_id' fields seem to be redundant (and confusing) as you already have an entity mapping in the form of your 'blog' property.
回答2:
This question is pretty old, but for any future reference i have found this answer that solved my problem.
After numerous searchers around the web I found this answer here - thanks to jtal!
Just to summaries the problem:
Using Ebean i have made a @ManyToOne entity that is not implemented in the database in anyway, even more the join field, in your case
blogId
is a valid field that has values of its own.
when trying to join the column on that field, it will always fail because it creates this sql query:
SELECT
*
FROM
blog_comment;
select
t0.id c0,
t0.blog_id c1,
t0.content c2,
t0.website c3,
t0.time_created c4,
t0.blog_id c5 <---- notice this duplicate
from
blog_comment t0
in order to solve this, i tell ebean not to use the second set of properties.
your new ebean element should look something like this:
@ManyToOne
@JoinColumn(name = "blogId", insertable = false, updatable = false)
public Blog blog;
hope this helps! =)
来源:https://stackoverflow.com/questions/24377478/persistenceexception-column-id-specified-twice