I want to insert and retrieve a a user defined Object in DB,am using Mysql5.1.
1)What should me the data type for the column(is Blob is the correct answer for this question)
I am using EntityClass to Insert/Get values from the DB.
2)but to how to insert Object in database?
The common way is to translate the object to a table - every field of the object is (toughly) translates to a column of the table. The term for this is object relational mapping. There is plenty of documentation of this on the web (like this) as this is one of the cornerstones of modern day enterprise development.
There are several libraries you can use, and the best is to stick to the standard called JPA - Java Persistence API. The most known libraries (all open source) are
Hibernate
EclipseLink
OpenJPA
Your user defined object will look like this :
#Entity
#Table(name = "some_table")
public class SomeObject implements Serializable {
static final long serialVersionUID = <some value>;
#Id
#GeneratedValue
protected Long id;
#Column
protected String name;
#Column
protected int value;
// default constructor
// getters, setters
// equals, hashCode, toString
// other methods
}
Related
I'm trying to use the jOOQ fetchInto() method to map to an existing Hibernate model Organization (class and its inheritances are below).
Organization organization = jooq().select().from(ORGANIZATION).fetchOne().into(Organization.class);
The problem I have is that I can't really understand what happens in DefaultRecordMapper as I feel I'm not entirely familiar with all the terms that are used. I'm trying to figure out how it applies to the Hibernate classes that are in my codebase.
So far what I've tried:
Use the jOOQ generated POJO's to see if it retrieves and maps the data at all (works).
Add a constructor, getters and setters to the Organization Hibernate model.
Add #Column annotation to name in the Organization Hibernate model.
What works:
id field gets mapped correctly.
What doesn't work:
name field doesn't get mapped (null).
createdAt and modifiedAt fields do not get mapped (null).
My question is: Is there something I am overlooking with the mapping and what are the things I should look at concerning the classes, fields, constructors and annotations with Hibernate models? I want to eventually map all the Hibernate models in the codebase and use fetchInto to do that.
Thanks! :)
#Entity
public class Organization extends BaseModel {
#Required public String name;
//... a lot of other code
}
#MappedSuperclass
public class BaseModel extends Model {
/** The datetime this entity was first saved. Automatically set by a JPA prePersist */
#NoBinding
#Column
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime createdAt;
/** The datetime this entity was last modified. Automatically set by a JPA preUpdate */
#NoBinding
#Column
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime modifiedAt;
//...
}
#MappedSuperclass
public class Model extends GenericModel { // Both Model and GenericModel are from the Play Framework
#Id
#GeneratedValue
public Long id;
public Model() {
}
public Long getId() {
return this.id;
}
public Object _key() {
return this.getId();
}
}
jOOQ doesn't support all the many JPA and Hibernate specific annotations. Historically, it supported a few JPA annotations (because why not), but full interop would be excessive and investing product development time in the wrong places. jOOQ is by no means a JPA implementation.
Step 0: Why didn't (some) of the mappings work?
As mentioned before, not all JPA specification is implemented. For example, a known issue is that #Column annotations are still mandatory in jOOQ:
https://github.com/jOOQ/jOOQ/issues/4586
There might be other such limitations, which could be considered bugs. Feel free to report them if you want to continue down this path: https://github.com/jOOQ/jOOQ/issues/new/choose
But things like #MappedSuperclass or #Type are unlikely to ever be supported by jOOQ.
Step 1: Do you really need it?
You've decided to create and run your query with jOOQ. I imagine your actual query is much more complex than what you're showing, because for that particular query, you don't need jOOQ.
Do you really need to map to Hibernate entities? Because even when you use Hibernate, the recommended approach is to use entities only when you're going to modify them and store the delta back to the database. If that's the case, see step 2 below. If it's not the case, why not use jOOQ's own mapping functionality to work with any style of jOOQ supported POJO?
Step 2: Use Hibernate to execute the jOOQ query
If you're using jOOQ only to build a rather complex SQL query and you need Hibernate entities as a result, then use Hibernate to execute the jOOQ query as documented here. A small utility should be enough:
public static <E> List<E> nativeQuery(EntityManager em, org.jooq.Query query, Class<E> type) {
Query result = em.createNativeQuery(query.getSQL(), type);
List<Object> values = query.getBindValues();
for (int i = 0; i < values.size(); i++)
result.setParameter(i + 1, values.get(i));
return result.getResultList();
}
I have an indexed entity, like below :
#MappedSuperclass
public static class Model{
#Id
#GeneratedValue(strategy=GenerationType.Identity)
private Integer id;
private boolean isDeleted;
}
and the indexed class is :
#Entity
#Table("USERS")
#Indexed
public class ProductModel extends Model{
#Field
private String name;
//getters & setters
}
Well, when I do a research on ProductModel, I get the value of the flag isDeleted while its not annotated with #Field.
I'm asking if this is a normal behavior, does Hibernate-search Index the whole Object Or does it fetch the missing data from data base, I need an explanation for this behavior please.
Hibernate Search only stores in the index the fields you declare explicitly (more precisely, it indexes by default and you can ask Hibernate Search to store it by adding the store option to your #Field annotation).
What you observe is that Hibernate Search hydrates the objects with the information of the database after having performed the search. This is one of the main interest in using Hibernate Search: the objects returned are managed entities.
Lets say I have a class in which i generate a DB with some keys, now I want to have an other class in which i use for example the "key123" as I named it in the following, how can I do that? Is that possible to just copy&paste the #Basic and public String key123 in that other class? Will that Basic annotation fetch it from the DB into that class? even when they both have different packages?
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic
#XmlAttribute
#XmlID
private Long id;
#Basic
private String someotherKey;
#Basic
public String key123;
You probably need to use the MVC model of development
Class Keys - the DB Table as an object using the #Entity annotation etc
Class KeysDao - The Data Access Object that does all the DB calls keysDao.update(Keys), keysDao.add(Keys), keysDao.get(id) keysDao.getAllKeys() etc.
Class KeyService - this has the Business Logic so you can say in any other class keyService.getKey(id) and get the Key from the DB returned. Then you can get it in any other class you wish.
If you mean get in another table you need to look at SQL table joins and create your query correctly (or create a view in the DB - not a lot of people know but you can update and add using a View meaning you can make one commit with the data as you use in the view and not have to even know the real normalised DB beneath.
I'm a bit confused about how getters and setters in JPA annotated POJO classes interact with a proposed MySQL database via Hibernate.
I understand that you can have, for example, the following:
#Entity
#Table(appliesTo = "users")
public class UserDM implements UserIF, Serializable {
private static final long serialVersionUID = 1L;
private long id;
private String name;
private Date createDate;
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String n) {
name = n;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(final long time) {
createDate = new Date(time);
}
}
Why is the auto ID generation strategy associated with the Getter?
How does that method actually auto-incremeent the ID when a new user is stored?
What is the order of operations? The POJO is filled via setters (or maybe a constructor?) and then the info is acquired by hibernate via getters and then stored into the db?
Is it a good idea to have my "getCreateDate" method return a date, or is it best to have the fields in pojos map to MySQL-friendly fields? If I wanted to get a Date object from a timestamp ms value, would the best way to do that be to use a transient mapped function?
Why is the auto ID generation strategy associated with the Getter?
This is a matter of taste, most of the time. You can put the annotations on fields or accessors (getters), depending on how you prefer, as long as it's consistent (always on methods, or always on properties). By setting it to the property, Hibernate will use reflection to get access to the property (it's not as bad as it sounds). By setting it to the method, Hibernate will use it instead of reflection.
How does that method actually auto-incremeent the ID when a new user is stored?
Not sure at which level of details you want the answer, but to keep it short: Auto will use the best auto-increment strategy for the database server you are using. It could be "identity" for Sybase/SQLServer, it could be "sequence" for Oracle-like or it could be "auto increment" for MySQL. Common to all those cases is the fact that Hibernate will not know the ID until the database generates it. After triggering an "insert", Hibernate will use a standard JDBC method to access the "generated id"
What is the order of operations? The POJO is filled via setters (or maybe a constructor?) and then the info is acquired by hibernate via getters and then stored into the db?
Again, I don't know which level of details you want this, but yes, that's the order. You fill the POJO and you call the persist method on the EntityManager, passing this POJO as parameter. Hibernate will then call the getters (or access the properties) and will send this data to the database.
Is it a good idea to have my "getCreateDate" method return a date, or is it best to have the fields in pojos map to MySQL-friendly fields? If I wanted to get a Date object from a timestamp ms value, would the best way to do that be to use a transient mapped function?
Try to keep your application "database agnostic". So, don't make it "mysql friendly" if you don't really need. In general, using a java.util.Date in a field mapped with #Temporal(TIMESTAMP) would do, but if you need more "powerful" date/time objects, like Joda-time, you can also use it (as long as you tell Hibernate how to use it).
Background:
My REST service project was started up by using Hibernate. I use id (Long) in domain class as part of the identifier in rest url, for example:
http://abc.com/customer-50, where 50 is the Long id.
The Hibernate Annotated class is as below:
public class Customer {
#Id
#GeneratedValue
private Long id;
}
Now I need to migrate our design to Mongodb. The natural choice is using Morphia, which is an entity framework.
Problem:
In Morphia, the id field is ObjectId
#Id private ObjectId id;
This will cause problem because:
1. It is not auto-increment, i.e. http://abc.com/customer-50, http://abc.com/customer-51, http://abc.com/customer-52.
Now it become http://abc.com/customer-4d1b4687a6d5437619000000
I will need to change all the reference classes from long to objectId.
Is it possible to keep the original design (which uses Long id, instead of ObjectId)?
Thanks!
Take a look at https://code.google.com/p/morphia/source/browse/trunk/morphia/src/main/java/com/google/code/morphia/utils/LongIdEntity.java https://github.com/mongodb/morphia/blob/master/morphia/src/test/java/org/mongodb/morphia/utils/LongIdEntity.java (link updated)
https://github.com/MorphiaOrg/morphia/blob/master/morphia/src/test/java/xyz/morphia/utils/LongIdEntity.java (updated again)