I'm currently working on a project that involves the use of Hibernate Search. Currently the project uses pure SQL for its searches and we would like to use a text search instead (Needing to know and correctly spell the first word can get annoying).
The schema is that a product can have multiple versions and the current version contains the name of the product.
Public Class Product extends ProgEntity
{
private List<ProductVersion> versions = new ArrayList<ProductVersion>();
...
}
Public Class ProductVersion extends ProgEntity
{
String productName;
...
}
I need to be able to search for a product based on its name. I was able to index the ProductVersions by productName with little issue however indexing Product is proving to be more of an issue.
After some research this is what I have however when I update the product to the DB no index is created.
#Entity
#Indexed
Public Class Product extends ProgEntity
{
#IndexedEmbedded
private List<ProductVersion> versions = new ArrayList<ProductVersion>();
...
}
#Entity
#Embeddable
Public Class ProductVersion extends ProgEntity
{
#Field
String productName;
...
}
The DocumentID is part of ProgEntity. I need to be sure that if I update Product or Product Version that it will be indexed properly which does not seem to be happening now.
Any suggestions on what I am doing incorrectly?
You don't have a relationship (eg many-to-one, many-to-one) between Product and ProductVersion mapped in the code you posted. This relationship must be bi-directional. Annotate the Product's collection field with #IndexedEmbedded, and the inverse field on the ProductVersion side with #ContainedIn, and you should be all set.
Using #Entity and #Embeddable on ProductVersion seems wrong. There are also some JPA annotations missing. Is the version collection mapped as #ManyToOne or #ElementCollection.
Have you checked your hibernate configuration and log files? Which directory provider are you using?
Related
I would like Hibernate to disable certain classes from being validated on startup.
My particular use-case:
spring.jpa.hibernate.ddl-auto=validate
#Table (name = "SAME_TABLE")
public class Entity1 {
#Column
private Long value;
// rest of values
}
#Table (name = "SAME_TABLE")
public class SearchEntity2 {
#Column
private String value;
// rest of values
}
As you can see I have two classes mapped to the same table called SAME_TABLE. This is because I want to do wildcard searches on numeric field value
JPA Validation fails on Oracle (h2 succeeds suprisingly) because it detects that the String is not NUMERIC(10).
This question here by #b0gusb provides an excellent way of filtering out via table name:
How to disable schema validation in Hibernate for certain entities?
Unfortunately my table name is identical. Is there any way of getting to the Java class name from SchemaFilteror perhaps another way of doing this?
Thanks
X
As activeandroid library suggests, when declaring a model class object to use annotation unique and index annotation parameters for unique constraint and indexing for a column respectively here,
/**activeandroid imports**/
import com.activeandroid.annotation.Column;
import com.activeandroid.Model;
....
#Table(name="Product")
public class Product extends Model{
...
/**issue: index is not a valid parameter for Column annotation**/
#Column(name = "Category", index = true)
public String category;
...
}
I tried to implement this but the annotation parameters index or unique are not available in the library.
I am using version 3.0 jar
Tried version3.1 beta also,same issue there.
While 3.1 is the latest jar available, am I missing something? Please suggest a solution to create indexes when using activeandroid library.
Thanks
Check if you are extending the Model in your Category Class
public class Category extends Model {}
if no, please post the entire Class and Error log.
I'm using toplink JPA in a webapp and I want to map just one table to a class hierarchy. I want to have one class that represents most of the data, and one class that inherits from that (so it gets all the fields of the superclass, plus a couple of other that hold large amounts of data). I don't want the large amounts of data all the time, don't want to hold them in request objects etc. I only want the large bits when someone has selected one of the summaries. I've setup the classes as follows (simplified as an example).
#Entity
#Table(name = "TRANSCRIPTS")
#MappedSuperclass //also tried without this - same error
public class Summary {
#Id
#Column(name = "id")
private long id;
#Column(name = "title")
private String title;
//rest of class etc.
}
#Entity
#Table(name = "TRANSCRIPTS")
public class Detail extends Summary {
#Id
#Column(name = "fullText")
private String fullText;
//rest of class etc.
}
When I try and get data using this hierarchy, I get an error along the lines of
Unknown column 'DTYPE'
So it's looking for a descriminator column. Which I haven't setup, because it's not that sort of relationship.
Is there a different way I can map this summary/detail relationship in JPA? Or should I give up on the class inheritance and have two separate unrelated classes, one representing summary data and one representing the full data (and redefining the summary fields).
Thanks.
DTYPE it is discriminator column that Toplink tries to access to choose between your entities,
If you add that column to your table schema, it will start working.
DTYPE is INTEGER typed column in database.
You could specify your own discriminator column using following code snippet:
#Entity
#DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.INTEGER)
#DiscriminatorValue("1")
class TestClass {}
Here is some documentation for you http://www.oracle.com/technetwork/middleware/ias/toplink-jpa-annotations-096251.html#CHDJHIAG
I have a problem with my code (obviously) and after many searches on Internet, I don't find an answer to my problem, so I ask my question here.
I have this :
#Entity
public class Resident
{
/** Attributes */
#EmbeddedId
private IdResident idResident;
...
#Embeddable
public class IdResident {
#Column(name="NOM")
private String nom;
#ManyToOne
#JoinColumn(name="CODE")
private Port port;
...
#Entity
public class Port
{
/** Attributes */
#Id
#Column(name="CODE")
private String code;
#Column(name="NOM")
private String nom;
...
And I'm using Maven, I've write this in my persistence.xml :
<class>beans.Port</class>
<class>beans.Resident</class>
But when i run the program, no matter what i've write, I have this :
Exception Description: The mapping [port] from the embedded ID class
[class beans.IdResident] is an invalid mapping for this class. An embeddable class that
is used with an embedded ID specification (attribute [idResident] from the source
[class beans.Resident]) can only contain basic mappings. Either remove the non
basic mapping or change the embedded ID specification on the source to be embedded.
I don't see where is my mistake, I think it's because of the IdResident class wich has an Entity object in it, but I don't know how to fiw it
Error message you get explains it quite well, Embeddable that is used as an embedded id can contain only basic mappings, not relationships. In JPA 2.0 specification this is told with following words:
Relationship mappings defined within an embedded id class are not
supported.
Just define attributes that are part of composite id in embeddable that is used as embedded id, and map relationships in entity itself (or in another embeddable and include mappings with #Embedded).
In my opinion this is based on the ManyToOne mapping in the IdResident class cause the error message pushs me into this direction.
I have a Person entity mapped by Hibernate to a database table in a database catalog "Active". After a period of time, records in this database table in the "Active" catalog are archived/moved to an exact copy of the table in a database Catalog "History". I have the need to retrieve from both the Active and History Catalogs. Is there a better way to model this with Hibernate annotations than making an abstract class that 2 classes extend from.
This is what I have now.
#MappedSuperclass
public abstract class Person {
#Id
private Integer id;
private String name;
}
#Entity
#Table(name="Person", catalog="Active")
public class PersonActive extends Person {
}
#Entity
#Table(name="Person", catalog="History")
public class PersonHistory extends Person {
}
To my knowledge, that would be the right way to do it with annotations (you kinda have two tables so you need two entities). Then run a polymorphic query on the Person entity. I find this pretty clean by the way.
PS: Can you add a pointer on how to do this with mapping files, I'm really curious.
My thought would be to write a query to select both tables from db A and B. then create a query with hibernate and map it to your class.
example:
#Entity
#NamedNativeQuery(
name="GetAllPerson",
query="select * from A.Person inner join B.Person on A.Person.Id = B.Person.Id"
)
public class Person {
...
}
Not sure if it could work, your question made me also curious about the best way to do it :). I'll test it tonight after work and see if its any good.
I think there is a subproject of hibernate named shards. It is designed to work with multiple relational databases. If you want to use it, you may need big changes in your code.