Hibernate error reading data from database - java

I have created an application using Spring MVC 3, Hibernate and Ext Js 4. The problem is that when I start the application the data is not readed from the database.
BookController.java:
#Controller
public class BookController {
private BookService bookService;
#RequestMapping(value="/books/view.action")
public #ResponseBody Map<String,? extends Object> view(#RequestParam int start, #RequestParam int limit) throws Exception {
try{
List<Book> books = bookService.getBookList(start,limit);
int total = bookService.getTotalBooks();
return ExtJSReturn.mapOK(books, total);
} catch (Exception e) {
return ExtJSReturn.mapError("Error retrieving books from database.");
}
}
BookService.java:
#Service
public class BookService {
private BookDAO bookDAO;
/**
* Get all books
* #return
*/
#Transactional(readOnly=true)
public List<Book> getBookList(int start, int limit){
return bookDAO.getBooks(start, limit);
}
public int getTotalBooks(){
return bookDAO.getTotalBooks();
}
BookDAO.java:
#SuppressWarnings("unchecked")
public List<Book> getBooks(int start, int limit) {
DetachedCriteria criteria = DetachedCriteria.forClass(Book.class);
return hibernateTemplate.findByCriteria(criteria, start, limit);
}
public int getTotalBooks(){
return DataAccessUtils.intResult(hibernateTemplate.find("SELECT COUNT(*) FROM books"));
}
Book.java:
#JsonAutoDetect
#Entity
#Table(name="books")
public class Book {
#Id
#GeneratedValue
#Column(name="id")
private int id;
#Column(name="title", nullable=false)
private String title;
#Column(name="author", nullable=false)
private String author;
#Column(name="publisher", nullable=false)
private String publisher;
#Column(name="isbn", nullable=false)
private String isbn;
#Column(name="pages", nullable=false)
private int pages;
#Column(name="category", nullable=false)
private String category;
#Column(name="qty", nullable=false)
private int qty;
/**
* #return the title
*/
public String getTitle() {
return title;
}
/**
* #param title the title to set
*/
public void setTitle(String title) {
this.title = title;
}
/**
* #return the author
*/
public String getAuthor() {
return author;
}
/**
* #param author the author to set
*/
public void setAuthor(String author) {
this.author = author;
}
/**
* #return the publisher
*/
public String getPublisher() {
return publisher;
}
/**
* #param publisher the publisher to set
*/
public void setPublisher(String publisher) {
this.publisher = publisher;
}
/**
* #return the isbn
*/
public String getIsbn() {
return isbn;
}
/**
* #param isbn the isbn to set
*/
public void setIsbn(String isbn) {
this.isbn = isbn;
}
/**
* #return the pages
*/
public int getPages() {
return pages;
}
/**
* #param pages the pages to set
*/
public void setPages(int pages) {
this.pages = pages;
}
/**
* #return the category
*/
public String getCategory() {
return category;
}
/**
* #param category the category to set
*/
public void setCategory(String category) {
this.category = category;
}
/**
* #return the qty
*/
public int getQty() {
return qty;
}
/**
* #param qty the qty to set
*/
public void setQty(int qty) {
this.qty = qty;
}
/**
* #return the id
*/
public int getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(int id) {
this.id = id;
}
}
ExtJsReturn.java:
#Component
public class ExtJSReturn {
/**
* Generates modelMap to return in the modelAndView
* #param books
* #return
*/
public static Map<String,Object> mapOK(List<Book> books){
Map<String,Object> modelMap = new HashMap<String,Object>(3);
modelMap.put("total", books.size());
modelMap.put("data", books);
modelMap.put("success", true);
return modelMap;
}
/**
* Generates modelMap to return in the modelAndView
* #param books
* #return
*/
public static Map<String,Object> mapOK(List<Book> books, int total){
Map<String,Object> modelMap = new HashMap<String,Object>(3);
modelMap.put("total", total);
modelMap.put("data", books);
modelMap.put("success", true);
return modelMap;
}
/**
* Generates modelMap to return in the modelAndView in case
* of exception
* #param msg message
* #return
*/
public static Map<String,Object> mapError(String msg){
Map<String,Object> modelMap = new HashMap<String,Object>(2);
modelMap.put("message", msg);
modelMap.put("success", false);
return modelMap;
}
}
The error is raised from the controller: Error retrieving books from database.
Do you have any ideea what can be the problem?
See here the Console output: http://pastebin.com/jMQKS31P
FIXED!!!
https://stackoverflow.com/a/14447201/1564840

You're passing a SQL request, using tables and column names, to a method which expects an HQL request, using entities, mapped fields and associations. SQL and HQL are two different query languages.
The HQL query should be
select count(book.id) from Book book
If you don't know about HQL, then you really need to read the documentation. Using Hibernate without knowing HQL is like using JDBC without knowing SQL.

Related

Create Dynamic JPA Query

I have a view with many fields as query filters, and I am using JPA derived queries , however creating all queries for every combination of fields/filters would be tedious and long.
I found out that I can create a dynamic query for it, but not sure how.
So far I have created these queries in my repository, but still need a lot more :
public interface EmployeeReportInfoViewRepository extends PagingAndSortingRepository<EmployeeReportInfo, Long> {
List<EmployeeReportInfo> findByControlNumber(String controlNmber);
List<EmployeeReportInfo> findByManager(String manager);
List<EmployeeReportInfo> findByofficeLocation(String officeLocation);
List<EmployeeReportInfo> findByBenchFlag(char benchFlag);
List<EmployeeReportInfo> findByBillableFlag(char billableFlag);
List<EmployeeReportInfo> findByEnableFlag(boolean enableFlag);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumber(String lastName, String firstName,String controlNumber);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManager(String lastName, String firstName,String controlNmber,String manager);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocation(String lastName, String firstName,String controlNmber,String manager,String officeLocation);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlag(String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlagAndBillableFlag(String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag,char bllableFlag);
List<EmployeeReportInfo> findByLastNameAndFirstNameAndControlNumberAndManagerAndOfficeLocationAndBenchFlagAndBillableFlagAndEnableFlagAndStartGreaterThanEqualAndEndLessThanEqual
(String lastName, String firstName,String controlNmber,String manager,String officeLocation, char benchFlag,char bllableFlag,
boolean emableFlag, Date start,Date end);
}
#Entity
#Table(name = "employee_report_view")
public class EmployeeReportInfo {
#Id
#Column(name = "employee_id")
private Long id;
private String name;
private Date start;
private Date end;
#Column(name = "control_number")
private String controlNumber;
#Column(name = "enable_flag")
private boolean enableFlag;
#Column(name = "billable_flag")
private char billableFlag;
#Column(name = "bench_flag")
private char benchFlag;
#Column(name = "office_location")
private String officeLocation;
#Column(name = "manager")
private String manager;
/**
* #return the id
*/
public Long getId() {
return id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* #return the start
*/
public Date getStart() {
return start;
}
/**
* #param start the start to set
*/
public void setStart(Date start) {
this.start = start;
}
/**
* #return the end
*/
public Date getEnd() {
return end;
}
/**
* #param end the end to set
*/
public void setEnd(Date end) {
this.end = end;
}
/**
* #return the controlNumber
*/
public String getControlNumber() {
return controlNumber;
}
/**
* #param controlNumber the controlNumber to set
*/
public void setControlNumber(String controlNumber) {
this.controlNumber = controlNumber;
}
/**
* #return the enableFlag
*/
public boolean isEnableFlag() {
return enableFlag;
}
/**
* #param enableFlag the enableFlag to set
*/
public void setEnableFlag(boolean enableFlag) {
this.enableFlag = enableFlag;
}
/**
* #return the billableFlag
*/
public char getBillableFlag() {
return billableFlag;
}
/**
* #param billableFlag the billableFlag to set
*/
public void setBillableFlag(char billableFlag) {
this.billableFlag = billableFlag;
}
/**
* #return the benchFlag
*/
public char getBenchFlag() {
return benchFlag;
}
/**
* #param benchFlag the benchFlag to set
*/
public void setBenchFlag(char benchFlag) {
this.benchFlag = benchFlag;
}
/**
* #return the officeLocation
*/
public String getOfficeLocation() {
return officeLocation;
}
/**
* #param officeLocation the officeLocation to set
*/
public void setOfficeLocation(String officeLocation) {
this.officeLocation = officeLocation;
}
/**
* #return the manager
*/
public String getManager() {
return manager;
}
/**
* #param manager the manager to set
*/
public void setManager(String manager) {
this.manager = manager;
}
}
I can understand your needs:you want to dynamically generate query conditions based on the url issued by the form.Let's assume that the url maps to the back end to a HashMap<String,String>.
For instance,url:
127.0.0.1/employees?nameContains=jack&ageEquals=10
Map:
HashMap<String, String>:key:nameContains,value:jack,key:ageEuqals,value:10
The Spring framework can do this mapping automatically(RequestParamMapMethodArgumentResolver). What you need to do is to dynamically generate the Specification(Specification) by this map.
Gets the type of property corresponding to the field using reflect : name=>String, age=>Integer
Using CriteriaBuilder to build query criteria,it has comprehensive api,such as:
Predicate like(Expression x, String pattern); => contains
Predicate equal(Expression x, Expression y); => equal
Assemble your query criteria(or,and)
You get a Specification.
This is a relatively complex solution idea, which requires the coordination between the front table component and the back end, but it will be very convenient.
What I said is relatively simple and general, there are a lot of details.(such as nested properties,one-to-one,one-to-many,etc)
Also,You can have a look http://www.querydsl.com/

Return List within List REST API Jax Rs

I am creating a REST API from java where I am returning an object list as follows:
#Path("/order")
public class OrderService implements IService
{
#Override
public Response get()
{
List<DataObj> list = new ArrayList<>();
List<SubDataObj> subList = new ArrayList<>();
subList.add(new SubDataObj("1"));
GenericEntity<List<DataObj>> entity;
list.add(new DataObj("A", "22", TestEnum.test1, DateTime.now(), subList));
list.add(new DataObj("B", "23", TestEnum.test2, DateTime.now(), subList));
entity = new GenericEntity<List<DataObj>>(list){};
return Response.ok(entity).build();
}
}
Here the service returns the Response fine when not using the subList, which is a object list within the DataObj class. However, when I am using it, i get an error as:
SEVERE: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List<dyno.scheduler.restservice.DataObj>.
Here are the DataObj and the SubDataObj classes:
#XmlRootElement
class DataObj
{
private String name;
private String age;
private TestEnum enumVal;
private DateTime currentDate;
private List<SubDataObj> subData;
public DataObj(String name, String age, TestEnum enumVal, DateTime currentDate, List<SubDataObj> subData)
{
this.name = name;
this.age = age;
this.enumVal = enumVal;
this.currentDate = currentDate;
this.subData = subData;
}
public DataObj() {}
/**
* #return the name
*/
public String getName()
{
return name;
}
/**
* #param name the name to set
*/
public void setName(String name)
{
this.name = name;
}
/**
* #return the age
*/
public String getAge()
{
return age;
}
/**
* #param age the age to set
*/
public void setAge(String age)
{
this.age = age;
}
/**
* #return the enumVal
*/
public TestEnum getEnumVal()
{
return enumVal;
}
/**
* #param enumVal the enumVal to set
*/
public void setEnumVal(TestEnum enumVal)
{
this.enumVal = enumVal;
}
/**
* #return the currentDate
*/
public DateTime getCurrentDate()
{
return currentDate;
}
/**
* #param currentDate the currentDate to set
*/
public void setCurrentDate(DateTime currentDate)
{
this.currentDate = currentDate;
}
/**
* #return the subData
*/
public List<SubDataObj> getSubData()
{
return subData;
}
/**
* #param subData the subData to set
*/
public void setSubData(List<SubDataObj> subData)
{
this.subData = subData;
}
}
DataSubObj class:
class SubDataObj
{
private String subId;
public SubDataObj(String subId)
{
this.subId = subId;
}
/**
* #return the subId
*/
public String getSubId()
{
return subId;
}
/**
* #param subId the subId to set
*/
public void setSubId(String subId)
{
this.subId = subId;
}
}
I tried adding #XmlRootElement annotation to my SubDataObj class as well, which didn't work.
Any help would be appreciated!

Deserialize Array Of Objects with the first item being the counter of the elements

Hello i was trying to deserialize the following JSON response from a Web Api:
{
"response": [
370968,
{
"aid": 65843156,
"owner_id": 17519165,
"artist": "Bass Test",
"title": "дурной басс!",
"duration": 238,
"url": "http://cs6-10v4.vk-cdn.net/p22/c412a04df93035.mp3?extra=9YguhLftfZDDwo4JKBVwvlx_V1vwlu5pNU4-WremEqM9bL8eN2vh3_qu7bAg9EgNCj0ztEcMurarC499x8X2MpUaipykG2LDueWe0QQMrIPplkxKdV1xcQp35baDwA84l-luVxai9maX",
"lyrics_id": "6214304"
},
{
"aid": 207425918,
"owner_id": 96085484,
"artist": "► DJ Pleased",
"title": "Bass Test № 04 (New 2013)",
"duration": 328,
"url": "http://cs6-7v4.vk-cdn.net/p23/6d7071221fb912.mp3?extra=O5ih5W5YkaEkXhHQSOKeDzvtr0V8xyS1WhIgjYLROFOMcW__FpU3mSf5udwdEAq6kkcz7QSy5jB57rTgSxnRJXCySZy2b0J_a2DvzFUBqVX6lcKqlarTryP_loQyk-SYPbFLh-9mSzm_iA",
"lyrics_id": "86651563",
"genre": 10
}
]
}
My intention is to build a class to get the items in the response and use them in my Java Android application. The problem is that the first item of the response array is a number and not an object like the next items. So when I parse it with Gson it gives me the error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 20 path $.response[0]
I used the retrofit android library with the following POJO class (witch works if i don't have the counter in the response):
import java.util.HashMap;
import java.util.Map;
public class Response {
private Integer aid;
private Integer ownerId;
private String artist;
private String title;
private Integer duration;
private String url;
private String lyricsId;
private Integer genre;
private String album;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The aid
*/
public Integer getAid() {
return aid;
}
/**
*
* #param aid
* The aid
*/
public void setAid(Integer aid) {
this.aid = aid;
}
/**
*
* #return
* The ownerId
*/
public Integer getOwnerId() {
return ownerId;
}
/**
*
* #param ownerId
* The owner_id
*/
public void setOwnerId(Integer ownerId) {
this.ownerId = ownerId;
}
/**
*
* #return
* The artist
*/
public String getArtist() {
return artist;
}
/**
*
* #param artist
* The artist
*/
public void setArtist(String artist) {
this.artist = artist;
}
/**
*
* #return
* The title
*/
public String getTitle() {
return title;
}
/**
*
* #param title
* The title
*/
public void setTitle(String title) {
this.title = title;
}
/**
*
* #return
* The duration
*/
public Integer getDuration() {
return duration;
}
/**
*
* #param duration
* The duration
*/
public void setDuration(Integer duration) {
this.duration = duration;
}
/**
*
* #return
* The url
*/
public String getUrl() {
return url;
}
/**
*
* #param url
* The url
*/
public void setUrl(String url) {
this.url = url;
}
/**
*
* #return
* The lyricsId
*/
public String getLyricsId() {
return lyricsId;
}
/**
*
* #param lyricsId
* The lyrics_id
*/
public void setLyricsId(String lyricsId) {
this.lyricsId = lyricsId;
}
/**
*
* #return
* The genre
*/
public Integer getGenre() {
return genre;
}
/**
*
* #param genre
* The genre
*/
public void setGenre(Integer genre) {
this.genre = genre;
}
/**
*
* #return
* The album
*/
public String getAlbum() {
return album;
}
/**
*
* #param album
* The album
*/
public void setAlbum(String album) {
this.album = album;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
Is there any way to make it work? I don't have access to the API server so i cant change how the result is displayed. To generate the class i used http://www.jsonschema2pojo.org/ but i was able to generate it only by removing the counter from the response.
The wrapper class VKSongApi:
public class VKSongApi {
private List<Response> response = new ArrayList<Response>();
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The response
*/
public List<Response> getResponse() {
return response;
}
/**
*
* #param response
* The response
*/
public void setResponse(List<Response> response) {
this.response = response;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
The retrofit interface class is:
public interface VKApi {
#GET("/method/audio.search")
Call<VKSongApi> search(#Query("q") String query, #Query("access_token") String token);
}
Then in the MainActivity i do:
public static final String BASE_URL = "https://api.vk.com/method/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
VKApi apiService =
retrofit.create(VKApi.class);
And call the method from the MainActivity with:
Call<VKSongApi> call = apiService.search("test","fff9ef502df4bb10d9bf50dcd62170a24c69e98e4d847d9798d63dacf474b674f9a512b2b3f7e8ebf1d69");
call.enqueue(new Callback<VKSongApi>() {
#Override
public void onResponse(Call<VKSongApi> call, Response<VKSongApi> response) {
int statusCode = response.code();
VKSongApi song = response.body();
Log.d(TAG,response.message());
}
#Override
public void onFailure(Call<VKSongApi> call, Throwable t) {
//Here the error occurs com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 20 path $.response[0]
Log.d(TAG,"Failure");
}
});
I solved by parsing manually the response using a custom deserializer class

Android - Structure of classes for DB Tables + POJO Class can be same?

I have 25+ tables and I have used Content Provider with Database.
I have created separate files for each tables with following structure:
TProductUnit.java in package of com.myapp.db.tables
public class TProductUnit {
/***
* Fields of TABLE_PRODUCT_UNIT Table
***/
public static final String TABLE_PRODUCT_UNIT = "product_unit";
/**
* Columns of TABLE_PRODUCT_UNIT
*/
public static final String PRODUCT_UNIT_SERVER_ID = "id";
public static final String PRODUCT_UNIT_NAME = "name";
public static final String PRODUCT_UNIT_ITP = "itp";
public static final String PRODUCT_UNIT_UTP = "utp";
public static final String PRODUCT_UNIT_STATUS = "status";
public static String[] PRODUCT_UNIT_COLUMNS = new String[] {
BaseColumns._ID,
PRODUCT_UNIT_SERVER_ID,
PRODUCT_UNIT_NAME,
PRODUCT_UNIT_ITP,
PRODUCT_UNIT_UTP,
PRODUCT_UNIT_STATUS
};
}
ProductUnit.java is POJO class which will helpful when First time get data from Server.
public class ProductUnit {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("product_id")
#Expose
private Integer productId;
#SerializedName("url")
#Expose
private String url;
#SerializedName("bit")
#Expose
private int bit;
#SerializedName("status")
#Expose
private Integer status;
#SerializedName("itp")
#Expose
private String itp;
#SerializedName("utp")
#Expose
private String utp;
/**
* #return The id
*/
public Integer getId() {
return id;
}
/**
* #param id The id
*/
public void setId(Integer id) {
this.id = id;
}
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public int getBit() {
return bit;
}
public void setBit(int bit) {
this.bit = bit;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
/**
* #return The status
*/
public Integer getStatus() {
return status;
}
/**
* #param status The status
*/
public void setStatus(Integer status) {
this.status = status;
}
/**
* #return The itp
*/
public String getItp() {
return itp;
}
/**
* #param itp The itp
*/
public void setItp(String itp) {
this.itp = itp;
}
/**
* #return The utp
*/
public String getUtp() {
return utp;
}
/**
* #param utp The utp
*/
public void setUtp(String utp) {
this.utp = utp;
}
/**
* Convenient method to get the objects data members in ContentValues object.
* This will be useful for Content Provider operations,
* which use ContentValues object to represent the data.
*
* #return
*/
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put(PRODUCT_UNIT_SERVER_ID, id);
values.put(PRODUCT_UNIT_NAME, name);
values.put(PRODUCT_UNIT_ITP, itp);
values.put(PRODUCT_UNIT_UTP, utp);
values.put(PRODUCT_UNIT_STATUS, status);
return values;
}
}
Both classes have most of the same number of fields with same values if we think about #SerializedName
Problem:
Whenever I need to add some fields in any Particular Table then I have to add in all Table file and JSON POJO Class too.
When any field name changed by server side then I have to change in both file.
My Question is: Is there any better solution for this optimization. Have you ever manage like this?
P.S. I have 25+ tables so I have to create 50+ classes.
Help please. Thanks.

JPA Hibernate Saving ManyToOne field is null

I have a servlet method that creates a JPA entity and assigns an existing JPA entity to a #ManyToOne field
When I persist it, it saves the entity but the foreign key is NULL. Why?
Here are my entities:
#Entity
public class SimpleEntity implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -5930519292861829894L;
#Id #GeneratedValue
Long id;
String name;
#ManyToOne()
#JoinColumn(name="simple_entity_group_id", insertable=false, updatable=false, nullable=true)
SimpleEntityGroup group;
/**
*
*/
public SimpleEntity() {
}
/**
* #return the id
*/
public Long getId() {
return this.id;
}
/**
* #param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return this.name;
}
/**
* #param name the name to set
*/
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
return "SimpleEntity [id=" + this.id + ", name=" + this.name + ", group=" + this.getGroup() + "]";
}
/**
* #return the group
*/
public SimpleEntityGroup getGroup() {
return this.group;
}
/**
* #param group the group to set
*/
public void setGroup(SimpleEntityGroup group) {
this.group = group;
}
}
#Entity
public class SimpleEntityGroup implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1680386377742600266L;
#Id #GeneratedValue
Long id;
String name;
#OneToMany(mappedBy="group")
java.util.List<SimpleEntity> simpleEntities;
/**
*
*/
public SimpleEntityGroup() {
simpleEntities = new ArrayList<SimpleEntity>();
}
/**
* #return the id
*/
public Long getId() {
return this.id;
}
/**
* #param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return this.name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the simpleEntities
*/
public java.util.List<SimpleEntity> getSimpleEntities() {
return this.simpleEntities;
}
/**
* #param simpleEntities the simpleEntities to set
*/
public void setSimpleEntities(java.util.List<SimpleEntity> simpleEntities) {
this.simpleEntities = simpleEntities;
}
public void addSimpleEntity(SimpleEntity e) {
if(this.getSimpleEntities() != null) {
this.getSimpleEntities().add(e);
return;
}
throw new RuntimeException("Entity list is null!!!");
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
return "SimpleEntityGroup [id=" + this.id + ", name=" + this.name + "]";
}
/* (non-Javadoc)
* #see java.lang.Object#hashCode()
*/
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
return result;
}
/* (non-Javadoc)
* #see java.lang.Object#equals(java.lang.Object)
*/
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
SimpleEntityGroup other = (SimpleEntityGroup) obj;
if (this.id == null) {
if (other.id != null) {
return false;
}
} else if (!this.id.equals(other.id)) {
return false;
}
return true;
}
}
Here is how I persist it:
SimpleEntity e = new SimpleEntity();
e.setName("Mike");
SimpleEntityGroup g = dao.getGroupById(1l);
e.setGroup(g);
dao.persist(e);
System.out.println(e);
System.out.println(dao.findAll());
Here is the output from the Java code, the group is set on the entry but it is not saved. Why?!?!
SimpleEntity [id=4, name=Mike, group=SimpleEntityGroup [id=1,
name=Group 1]]
[SimpleEntity [id=4, name=Mike, group=null]]
Of course I just figured it out, needed to do:
#ManyToOne()
#JoinColumn(name="simple_entity_group_id")
SimpleEntityGroup group;
-- Got rid of the insert=false, update=false
You only posted your child class but I think will be better if you also include the parent class code. I had the same problem when I tried make saves in cascade using only auto generated ids. I could solve it using the next annotations.
In my parent class I have
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="IDCOBPRES", unique=true, nullable=false)
public Long getIdcobpres() {
return this.idcobpres;
}
//....
#OneToMany(fetch=FetchType.LAZY, mappedBy="cobpresGestion")
#Cascade({CascadeType.ALL})
public Set<CobpresOptionDet> getCobpresOptionDets() {
return this.cobpresOptionDets;
}
In my child class I have
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="IDOPTIONDET", unique=true, nullable=false)
public Long getIdoptiondet() {
return this.idoptiondet;
}
//...
#ManyToOne(fetch=FetchType.LAZY, optional=false)
#JoinColumn(name="IDCOBPRES", nullable=false, insertable=true, updatable=true)
public CobpresGestion getCobpresGestion() {
return this.cobpresGestion;
}

Categories

Resources