N´Abend,
ich hatte letzte Woche schon etwas in das englische Forum geschrieben, aber leider bisher noch keine Antwort erhalten.
Da mir leider bisher noch nichts zur Lösung des Problems eingefallen ist, poste ich es auch noch mal hier.
Das Problem liegt daran das meiner Meinung nach der Lucene Index nicht richtig erstellt wird.
Das Problem betrifft aber nur die ManyToMany Verknüpfungen.
Es werden z.b. die IDs der Areas und Languages in dem selben ID Feld der Ressourcen gespeichert.
Und nicht zum Beispiel in areas.id
Hatte mich an folgende Literatur gehalten:
http://laliluna.de/articles/java-persis ... omany.htmlhttp://www.laliluna.de/jpa-hibernate-guide/ch07s06.htmlhttp://docs.redhat.com/docs/en-US/JBoss ... -en-US.pdfVielleicht hat hier ja noch jemand eine Idee woran es liegen könnte.
Thx!
Resource.java
Code:
@Entity
@Indexed
@Table(name="Resources")
@XmlRootElement(namespace="www.xxx.de", name="resource")
@JsonIgnoreProperties(value={"users","languages","areas","collections"})
public class Resource extends Transformable {
protected Long id = null;
protected String uuid = null;
protected String name = null;
protected String description = null;
…
protected ResourceType type = null;
protected Set<Language> languages = null;
protected Set<Tag> tags = null;
protected List<User> users = null;
protected Set<Area> areas = null;
…
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "resourceId")
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
…
// Hier funktioniert die Indexierung wunderbar! Bsp. Type.id:2
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "resourcetypeId", nullable = true, referencedColumnName = "resourcetypeId")
@IndexedEmbedded(depth=1,targetElement=ResourceType.class)
@JsonIgnore
@XmlTransient
public ResourceType getType() {
return type;
}
public void setType(ResourceType type) {
this.type = type;
}
…
/* Hier wird zwar der index erstellt, allerdings befindet sich die IDs der areas auch in dem Feld IDs in dem sich bereits die RessourcenIDs befinden. Daher ist eine Suche über den Index nicht Sinnvoll wenn ich nur Ressourcen eines bestimmten areas haben möchte. Bsp. Areas.id:2
*/
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@IndexedEmbedded(depth = 1)
@JoinTable(name = "resources_areas", joinColumns = {@JoinColumn(name = "resourceId")}, inverseJoinColumns = {@JoinColumn(name = "areaId")})
@XmlTransient
@JsonIgnore
public Set<Area> getAreas() {
return areas;
}
public void setAreas(Set<Area> areas) {
this.areas = areas;
}
// Gleiches auch hier
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@IndexedEmbedded(depth = 1)
@JoinTable(name = "resources_collections", joinColumns = {@JoinColumn(name = "resourceId")}, inverseJoinColumns = {@JoinColumn(name = "collectionId")})
@XmlTransient
@JsonIgnore
public Set<Collection> getCollections() {
return collections;
}
public void setCollections(Set<Collection> collections) {
this.collections = collections;
}
// und hier
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@IndexedEmbedded(depth = 1)
@JoinTable(name = "resources_languages", joinColumns = {@JoinColumn(name = "resourceId")}, inverseJoinColumns = {@JoinColumn(name = "languageId")})
@XmlTransient
@JsonIgnore
public Set<Language> getLanguages() {
return languages;
}
public void setLanguages(Set<Language> language) {
this.languages = language;
}
Area.java
Code:
@Entity
@Indexed()
@Table(name = "Areas")
@XmlRootElement(namespace="www.xxx.de", name="area")
public class Area extends Transformable {
protected Long id = null;
protected String code = null;
protected Set<Resource> resources = null;
protected Set<Collection> collections = null;
protected URI uri = null;
protected List<URI> resourceUri = null;
protected List<URI> collectionUri = null;
public void transform(UriInfo uriInfo) {
resourceUri = new LinkedList<URI>();
collectionUri = new LinkedList<URI>();
setUri(uriInfo.getAbsolutePathBuilder().path(getId().toString()).build());
for(Resource r : getResources())
resourceUri.add(uriInfo.getBaseUriBuilder().path("resource").path(r.getId().toString()).build());
for(Collection c : getCollections())
collectionUri.add(uriInfo.getBaseUriBuilder().path("collection").path(c.getId().toString()).build());
setResourceUri(resourceUri);
setCollectionUri(collectionUri);
}
@Transient
public URI getUri() {
return uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
@Transient
@XmlElementWrapper(name="resources")
public List<URI> getResourceUri() {
return resourceUri;
}
public void setResourceUri(List<URI> resourceUri) {
this.resourceUri = resourceUri;
}
@Transient
@XmlElementWrapper(name="collections")
public List<URI> getCollectionUri() {
return collectionUri;
}
public void setCollectionUri(List<URI> collectionUri) {
this.collectionUri = collectionUri;
}
public Area() {}
public Area(String code) {
this.code = code;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="areaId")
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "code", unique = true, nullable = false)
@Field(store = Store.YES, index = Index.UN_TOKENIZED)
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@ManyToMany(mappedBy = "areas")
@IndexedEmbedded(depth = 1)
@XmlTransient
@JsonIgnore
public Set<Resource> getResources() {
return resources;
}
public void setResources(Set<Resource> resources) {
this.resources = resources;
}
@ManyToMany(mappedBy = "areas")
@IndexedEmbedded(depth = 1)
@XmlTransient
@JsonIgnore
public Set<Collection> getCollections() {
return collections;
}
public void setCollections(Set<Collection> collections) {
this.collections = collections;
}
}
ResourceType.java
Code:
@Entity
@Indexed
@Table(name="ResourceTypes")
@XmlRootElement(namespace="www.xxx.de", name="resourceType")
public class ResourceType extends Transformable {
protected Long id = null;
protected String code = null;
protected URI uri = null;
protected List<URI> resourcesUri = null;
@Transient
public URI getUri() {
return uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
@Transient
@XmlElementWrapper(name="resources")
public List<URI> getResourcesUri() {
return resourcesUri;
}
public void setResourcesUri(List<URI> resourcesUri) {
this.resourcesUri = resourcesUri;
}
public ResourceType() {
}
public ResourceType(String code) {
this.code = code;
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="resourcetypeId")
@DocumentId
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
@Field(index = Index.TOKENIZED, store = Store.NO)
@Column(name="code", unique=true, nullable=false)
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public void transform(UriInfo uriInfo) {
// TODO Auto-generated method stub
}
}
Hier mal Screenshots meines Indexes (Erstellt mit Luke:
http://code.google.com/p/luke/):
Good:
Bullshit: