2013-07-08 2 views
0

Скажем, у меня есть класс ClassA и класс ClassB. ClassA поддерживает ссылку на список с зависимостью OneToManny и имеет идентификатор, заданный приложением. ClassB не имеет ссылки на ClassA. Зависимость является однонаправленной.JPA Entity с идентификатором от ссылочного класса

Поскольку каждый объект JPA требует идентификатора, я должен указать Id для ClassB, но идентификатор для ClassB состоит из Id и ClassB идентификатора ClassA. Есть ли способ моделировать это, не добавляя ссылку от ClassB на ClassA (я знаю, что я могу использовать @ManyToOne и @JoinColumn в этом случае)?

EDIT

Я пытаюсь использовать @Embeddable и @ElementCollection, но я получаю AnnotationException: List/array has to be annotated with an @OrderColumn (or @IndexColumn): my.package.PoiDetails.tips.

Вот полный код (взять PoiDetails в ClassA и Comment как ClassB). Как вы можете предположить, первичный ключ Comment представляет собой комбинацию из User 's id, Comment' s timestamp и Poi 's id.

ClassA:

@Entity 
public class PoiDetails implements Serializable { 

private static final long serialVersionUID = 1L; 

@Id 
@OneToOne 
@JoinColumns(value = { 
     @JoinColumn(name="poiId", referencedColumnName="id"), 
     @JoinColumn(name="categoryId", referencedColumnName="categoryId"), 
     @JoinColumn(name="providerId", referencedColumnName="providerId")}) 
private Poi poi; 

@Transient 
private User[] peopleHere; 


@ElementCollection 
    @CollectionTable(
     name="tips" 
) 
private Comment[] tips; 

@ElementCollection 
    @CollectionTable(
     name="queries" 
) 
private Comment[] queries; 

} 

ClassB:

@Embeddable 
public class Comment implements Serializable { 

private static final long serialVersionUID = 1L; 
private String text; 
@OneToOne 
@JoinColumn(name="userId") 
private User user; 
private long timestamp; 

public Comment(String text, User user, long timestamp) { 
    super(); 
    this.text = text; 
    this.user = user; 
    this.timestamp = timestamp; 
} 
public Comment(){} 

public String getText() { 
    return text; 
} 
public void setText(String text) { 
    this.text = text; 
} 

public long getTimestamp() { 
    return timestamp; 
} 

public void setTimestamp(long timestamp) { 
    this.timestamp = timestamp; 
} 
public User getUser() { 
    return user; 
} 
public void setUser(User user) { 
    this.user = user; 
} 
} 

Poi:

@Entity 
public class Poi implements Serializable { 

private static final long serialVersionUID = 1L; 

@Id 
private long id; 
@Id 
private long categoryId; 
@Id 
private long providerId; 

private String title; 

private String description; 

private String positionLat; 

private String positionLong; 

private String positionAlt; 

public Poi(){} 

public Poi(long id, String title, String description, String positionLat, String positionLong, String positionAlt) { 
    this(id, -1, title, description, positionLat, positionLong, positionAlt); 
} 

public Poi(long id, long categoryId, String title, String description, String positionLat, String positionLong, String positionAlt) { 
    this.id = id; 
    this.categoryId=categoryId; 
    this.title = title; 
    this.description = description; 
    this.positionLat = positionLat; 
    this.positionLong = positionLong; 
    this.positionAlt = positionAlt; 
} 

public long getId() { 
    return id; 
} 
public void setId(long id) { 
    this.id = id; 
} 
public String getTitle() { 
    return title; 
} 
public void setTitle(String title) { 
    this.title = title; 
} 
public String getDescription() { 
    return description; 
} 
public void setDescription(String description) { 
    this.description = description; 
} 
public String getPositionLat() { 
    return positionLat; 
} 
public void setPositionLat(String positionLat) { 
    this.positionLat = positionLat; 
} 
public String getPositionLong() { 
    return positionLong; 
} 
public void setPositionLong(String positionLong) { 
    this.positionLong = positionLong; 
} 
public String getPositionAlt() { 
    return positionAlt; 
} 
public void setPositionAlt(String positionAlt) { 
    this.positionAlt = positionAlt; 
} 

public long getCategoryId() { 
    return categoryId; 
} 

public void setCategoryId(long categoryId) { 
    this.categoryId = categoryId; 
} 

public long getProviderId() { 
    return providerId; 
} 

public void setProviderId(long providerId) { 
    this.providerId = providerId; 
} 
} 

И Пользователь:

@Entity 
public class User implements Serializable { 

private static final long serialVersionUID = 1L; 
@Id 
private String id; 
private String nickname; 
private String thumbnailUrl; 

public User(){} 

public User(String userId, String nickname){ 
    this(userId, nickname, null); 
} 

public User(String id, String nickname, String thumbnailUrl) { 
    this.id=id; 
    this.nickname=nickname; 
    this.thumbnailUrl=thumbnailUrl; 
} 

public User(String userId) { 
    this.id=userId; 
} 
public String getId() { 
    return id; 
} 
public void setId(String userId) { 
    this.id = userId; 
} 

public void setNickname(String nickname) { 
    this.nickname=nickname; 
} 

public String getNickname() { 
    return nickname; 
} 

public String getThumbnailUrl() { 
    return thumbnailUrl; 
} 

public void setThumbnailUrl(String thumbnail) { 
    this.thumbnailUrl = thumbnail; 
} 

} 

ответ

1

Добавление ManyToOne - лучшее решение.

Вы также можете добавить Basic для поля внешнего ключа, но это не очень хороший дизайн.

Другой альтернативой является карта ClassB как Встраиваемый и использования и отображения ElementCollection,

See, http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection

+0

Я пытаюсь использовать Встраиваемый и ElementCollection, но я получаю в неприятности. См. Правки. – user1781028

+0

Использование списка не массива – James