When using Blob-fields in n-to-m-relations Hibernate and MSSQL are failing for some reason.
SQL Error: 421, SQLState: S0001
The image data type cannot be selected as DISTINCT because it is not comparable.
...
could not initialize a collection: [Dataset.documents#someID]
My classes look as follows:
@Entity
class Dataset {
@OneToMany(fetch = FetchType.LAZY)
public List<Document> documents = new Ar开发者_Go百科rayList<Document>();
}
@Entity
class Document {
@Id
public long id;
@Lob
public byte[] data;
}
Any ideas on this? I already tried using a Set
or Document[]
to avoid the errors. It seems that Hibernate always tries a distinct SELECT on my tables. How can I workaround this?
[1] MSSQL error codes
It would have been interesting to post the executed queries and the tables. But one difference I can think of between the two mappings (unidirectional one-to-many vs a bidirectional) is the way they're represented at the database level.
By default, a unidirectional one-to-many will use a join table:
DATASET DATASET_DOCUMENT DOCUMENT
------- ---------------- --------
ID DATASET_ID ID
DOCUMENT_ID
While a bidirectional will use the following representation:
DATASET DOCUMENT
------- ----------
ID ID
DATASET_ID
In JPA 2.0, it is now possible to use a unidirectional association without a join table (in a standard way) by specifying a @JoinColumn
on the @OneToMany
side:
@Entity
class Dataset {
@Id
@Column(name="ID")
public Long id;
...
@OneToMany
@JoinColumn(name="DATASET_ID", referencedColumnName="ID")
public List<Document> documents = new ArrayList<Document>();
}
I would give the above a try.
References
- JPA 2.0 Specification
- Section 11.1.21 "JoinColumn Annotation"
- JPA Wikibook
- Undirectional OneToMany, No Inverse ManyToOne, No Join Table (JPA 2.0)
I managed to solve the problem by adding a reversed reference to my Document
class. I am sure there is a more direct way, because I do not need this reference at all, so it basically only helps to workaround the problem.
@Entity
class Dataset {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "dataset")
public List<Document> documents = new ArrayList<Document>();
}
@Entity
class Document {
@Id
public long id;
@Lob
public byte[] data;
@ManyToOne
@JoinColumn
public Dataset dataset;
}
I have fixed this in another way.
I already had the mappedBy = "enrollment"
on my OneToMay and on my ManyToOne I had a @JoinColumn(name="enrollment", nullable=true)
. So this was not a relation issue.
Instead I found a post on the hibernate forum suggesting overriding the supportsUnionAll()
from the Dialect class. It defaults returns false, but SQL Server has since v6.5 supported UNION ALL
. Remember the extend SQLServerDialect if you have not done so already.
So this could be another possible solution for the "The * data type cannot be selected as DISTINCT because it is not comparable" error.
精彩评论