An application is developed with JSF and JPA.
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
Bill is the Parent class and subclassed to OpdBill, PharmacyBill, etc.
Multiple users may try to persist at the same time.
It is easy to generate sequence number for the Bill class, but that is not essential in the functionality.
How can we have separate auto-generated sequence numbers for sub classes? (not necessary the ID, just a serial number)
As far as i know JPA is not able to create such Sequences for non ID-Columns, but you could do some dirty workaround like this:
Generate a secound entity like
#Entity
public class OpdSequence {
#Id
#GeneratedValue
private Long id;
}
and create a 1-1 to your OpdBill
#Entity
public class OpdBill extends Bill {
#OneToOne
private OpdSequence opdId;
}
If OpdBill is a Bill, then both must share the same ID field, and Hibernate must be able to distinguish two bills (whatever their class is) thanks to their IDs. All the subclasses must thus share the same ID generation with the base class, and the IDs of all the instances of Bill and its subclasses must be unique.
Related
Let's say we have such classes in the Java project:
#Entity
class Person {
#Id
String internalId;
#OneToMany
Set<Profession> profession;
}
#Entity
class Profession {
#Id
String id;
String professionName;
Integer yearsOfPractise;
}
In the business logic the professionName has to be unique per Person.
Is it correct to #override the equals with taking into the account only the professionName field and ingoring the others?
On the one hand such the equals can be handy if this class is handled from the business logic perspective. But such equals can be completely wrong and unhandy in cases when this class will have to be handled from some different perspective.
How to decide it?
Of course, this way you are using a business id, instead of the one that is probably generated by the jpa vendor and as a result, entities, that are manages are equal to the same that aren't.
For example if we create an entity, where the id is generated by the database and save it, the following gives no error:
Entity entity = new Entity();
Entity savedEntity = entityRepository.save(entity); // CrudReporitory
assertFalse(entity.equals(savedEntity));
In most cases it's not what we want. For more details I recommend this article.
You can overide the equals according to your business logic. In my case, I have excluded id.You can modify which fields are used with the lombok library:
https://projectlombok.org/features/EqualsAndHashCode
For Example:
#EqualsAndHashCode(exclude = "id")
public class Foo {
private Integer id;
}
Since, there are two cases:
comparing two entities by equality (content)
comparing two entities by an identifier
You should not override equals to do either or. This would be confusing. Instead use a dedicated function for each. This way you/or anyone else reading the code can choose the correct one and this choice will be obvious to the reader.
Is it possible to annotate a class as #Embeddable or a property as #Embedded?
Sample code:
#Embeddable
class A{
...
}
class B{
...
}
#Entity
class Foo {
A a;
#Embedded B b;
}
When to prefer #Embedded and #Embeddable?
There are two primary uses for #Embedded/#Embeddable as far as I know:
First, and most important: Splitting up large entity classes. In the database world, a large table (one with many columns) is fine. Breaking up such a table might even make things worse, and be in collision with database design principles. In Java (or object oriented languages in general), on the other hand, a large class is a code smell. Here, we would like to split the classes, including entity classes, into smaller units. #Embedded/#Embeddable allows us to easily do this without having to split the database table.
Second, it allows for reuse of common mappings between entities. Say each table has a simple revision tracking, with two columns containing the username of the person who changed the row, and the time it happened. Then, one can make an #Embeddable entity covering these rows, and then reuse this across all entities by embedding it (rather than repeating the variables corresponding to these columns in each entity.)
If we have Person and Address that are two POJOs, You would not want to create another table for Address but you would want to embed the address within the person table. So Address is adding up value to the Person object but doesn't make any sense individually. In this case we may go with:
#Embeddable
public class Address{
}
#Entity
public class Person
{
#Embedded
private Address address;
}
You would use #Embeddable and #Embedded together. You mark your class as #Embeddable, which indicates that this class will not exist in the DB as a separate table. Now when you use #Embedded on the field itself.
The word embeddable and embedded gives you a big clue actually.
Embeddable = This class can be embedded in a class
Embedded = This class will now be embedded in your class as a field.
I guess if you annotate class as #Embeddable you don't need to annotate field as #Embedded. Also, if you annotate class as #Embeddable and you want to use it as primary key, you can use #Id only, but if it is not annotated as #Embeddable, you have to use #EmbeddedId on field to work as primary key.
I need to create a database with 2 kinds of 'modules'.
domain focused classes
metadata classes
In the first group it is just simple (or complex rather) RDBMS. The second 'block' are metadata classes which collects information about classes from the first block.
What I have done:
Created Entity class which is parent of all fro 1st part:
#PersistenceAware
#Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
public abstract class Entity implements Serializable {
private static final long serialVersionUID = 1L;
}
Created normal schema with all entities inherit somehow Entity class.
Created InternalMapping class as a parent of the whole concept.
#PersistenceCapable
#Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
public abstract class InternalMapping implements Serializable {
private static final long serialVersionUID = 1L;
private Entity entity;
//.. cut off getter and setter
}
Created InternalMapping child which should have that feature.
Finally I found it does not work. Probably because Entity does not have any field. But if so I would expect 2 fields: a primary key and class name. In that way I would map every entity by 2 coordinates: ID and class name.
Any idea how to solve that issue? An finally how JDOQL would looks like.
Ps. I know that RDBMS is not the best solution for that kind of problems but people with whom I work wish to have relational database.
Finally I found solution for my problem. I am able to keep entities of different classes keep in one table. Also I am able to do JDOQL request with filtering instances of particular class.
The example is inside GitHub repository here: https://github.com/jgrzebyta/samples-jdo/tree/metalink and within metalink branch. It is slightly modified Tutorial project from datanucleus example.
So.
The lowest level in the inheritance hierarchy is Core interface with the PK defined inside.
Class MyIndex collects different implementations of the Core interface, i.e. Book and Product. Also I have added new column called type for storing Class names only. I am able to retrieve implementations of Core interface and build query filter against type filed because query type core instanceof Book simple does not work. That is the feature of the identity mapping strategy which I have used in my solution: DataNucleus JDO Objects.
PS. If you run command mvn -Pschema-gen compile than you will receive DDL file.
I have a Hibernate, spring and GWT application. I have two tables: Employee and user.
Every user is an employee and thus I have One To One relation in the database( they are joined by the primary keys) and thus User extends Employee. Things work fine when I insert user first, it auto inserts parents correctly. However, the problem is when I try to add the user entry for an existing employee, which instead of inserting the user record with the parent Id, it re-creates the employee record and user record.
#javax.persistence.Entity
#javax.persistence.Table(name = "User")
#Inheritance(strategy = InheritanceType.JOINED)
#PrimaryKeyJoinColumn(name="Id")
public class User extends Employee
{ .... }
#Reflectable(assignableClasses = true, superClasses = true)
#javax.persistence.Entity
#javax.persistence.Table(name = "Employee")
#Inheritance(strategy = InheritanceType.JOINED)
#PrimaryKeyJoinColumn(name="Id")
public class Employee
{
#Id
#GeneratedValue
#Column(name="Id")
public Integer getId()
{
return id;
}
}
Is this the right way to do things? How can I overcome this?
Thank you very much.
Update 1:
By Add user to it, I mean that I want to create a user with the same Id as employee.
which should basically become:
Insert into User (Id, username,..) Values (1, "Username", ...)
I do not think the existing mapping makes any sense.
I would suggest scrapping the inheritance and mapping a one-to-one (or one-to-many) relationship between Employee and say UserAccount.
I think that better reflects your model.
An employee may or not be a user of a system. Employees who are have a user account on that system.
If more systems amy be added in future then use a one-to-many. Employees have user accounts on zero, one or more systems.
Something doesn't sit right the first time I read your description and confirmed by your code snipet.
A few things you mentioned I break down into points:
Every user is an employee
I have OneToOne relation
User extends Employee
when I try to add the user entry for an existing employee
Just doesn't make sense.
Every User is an Employee and User extends Employee makes sense (somewhat)
but then why did you mention a One-to-One relation? There's no relation here, as also shown through your code.
A User is an Employee, but User does not own an Employee nor does an Employee own an User attribute (which is what "relationship" means).
Relationship is for example: an Employee has an Address, or a User has PermissionList.
And in the last point, when you said "add the user entry for an existing employee" shows that a User in this case supposed to be an attribute of an Employee and probably a List and not one-to-one (since you want to "add" to it).
Although if you step back, it doesnt make a lot of sense either because Employee does not own a User in the English sense.
A subclass / superclass is usually to describe a specific type of a more abstract type. eg. Dog is a subclass of an Animal because Dog is a specific type of Animal. Which I don't think what you want here.
I think you need to re think your design, and may be describe what you are trying to do.
Let's say I have the following class structure:
/** Boring bits snipped */
#Entity
#Table(name = "Foo")
public class Foo {
#JoinColumn(name = "id")
private Bar bar;
/** Other flat data goes here */
}
#Entity
#Table(name = "Bar")
public class Bar {
/** Some data goes here */
}
For reasons I'm not going to go into, I have copies of these tables which I want to also map too, which should appear in Java to also be Foo and Bar objects. Most importantly, the relationships between tables should be between the copied tables when dealing with copied objects.
What is the most correct way of doing this?
I'm guessing I can probably do something like this:
#Entity
#Table(name = "OtherFoo")
public class OtherFoo extends Foo {
#JoinColumn(name = "id")
private OtherBar bar;
}
#Entity
#Table(name = "OtherBar")
public class OtherBar extends Bar {
}
But is that the right way to do it?
You're close, but you can't just inherit from another entity and change the table like that. Entity inheritance has to follow one of the provided inheritance models. It may be for your use case as simple as adding #Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) to the superclass. There are some limitations to this if you have some more complicated mappings with other classes. Since it won't be able to tell which table a superclass based mapping is actually in, it can't join through it. And mappings to the superclass will require checking both tables every time. You also of course need unique ID generation across all the tables in the hierarchy. You may want to consider using an abstract superclass and having both concrete entities be leaf classes. Then at least you can always work with just a single table when you know which one it is.
Alternately you can declare your column mappings in an #MappedSuperclass and each subclass can then be an entity with a table mapping. That might work better if it's legacy data and you don't have unique IDs across the 'regular' and 'copy' tables.