I am converting software from Delphi to Spring boot. I have lots of queries in an existing SQL Server database, and I want to display them.
For every query, I have to create entity class, that override row mapper and create entity class.
public class PregledTroskova {
int RbrStavke;
int RbrNaloga;
String Konto;
String SifKomint;
float Duguje;
float Potrazuje;
public PregledTroskova() {
}
public int getRbrStavke() {
return RbrStavke;
}
public void setRbrStavke(int rbrStavke) {
RbrStavke = rbrStavke;
}
public int getRbrNaloga() {
return RbrNaloga;
}
public void setRbrNaloga(int rbrNaloga) {
RbrNaloga = rbrNaloga;
}
public String getKonto() {
return Konto;
}
public void setKonto(String konto) {
Konto = konto;
}
public String getSifKomint() {
return SifKomint;
}
public void setSifKomint(String sifKomint) {
SifKomint = sifKomint;
}
public float getDuguje() {
return Duguje;
}
public void setDuguje(float duguje) {
Duguje = duguje;
}
public float getPotrazuje() {
return Potrazuje;
}
public void setPotrazuje(float potrazuje) {
Potrazuje = potrazuje;
}
}
Then after that I have to write one more class for mapper
class PregledTroskovaRowMapper implements RowMapper<PregledTroskova> {
#Override
public PregledTroskova mapRow(ResultSet resultSet, int i) throws SQLException {
PregledTroskova pregledTroskova = new PregledTroskova();
pregledTroskova.setDuguje(resultSet.getFloat("Duguje"));
pregledTroskova.setPotrazuje(resultSet.getFloat("Potrazuje"));
pregledTroskova.setRbrStavke(resultSet.getInt("RbrStavke"));
pregledTroskova.setRbrNaloga(resultSet.getInt("RbrNaloga"));
pregledTroskova.setKonto(resultSet.getString("Konto"));
pregledTroskova.setSifKomint(resultSet.getString("SifKomint"));
return pregledTroskova;
}
}
Is there any way to just generate json list/array of object where property is result set name value for all rows from select?
If you don't want to create an entity class for every query, you can return a List<Map<String, Object>> which is a list of all rows, each row is represented by a Map (column / value).
Example :
final List<Map<String, Object>> rows = jdbcTemplate.queryForList(yourQuery);
for (final Map<String, Object> row : rows) {
// do something like : row.get("yourField");
}
Example :
String sql = "select * from mytable";
result= jdbcTemplate.query(sql, new AnyObjectMapper());
Mapper (generic) :
class AnyObjectMapper implements RowMapper<Map<String, Object>> {
public AnyObjectMapper() {
// TODO Auto-generated constructor stub
}
#Override
public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
ResultSetMetaData rsMeta = rs.getMetaData();
int colCount = rsMeta.getColumnCount();
Map<String, Object> columns = new HashMap<String, Object>();
for (int i = 1; i <= colCount; i++) {
columns.put(rsMeta.getColumnLabel(i), rs.getObject(i));
}
return columns;
}
}
Related
Im trying to access some list items from a json response using retrofit but cant seem to be able to access using get method. The ListQuotes seems to be saying null
#JsonPropertyOrder({
"page",
"last_page",
"quotes"
})
public class ListQuoteResponse {
#JsonProperty("quotes")
private List<Quote> quotes = null;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
* No args constructor for use in serialization
*
*/
public ListQuoteResponse() {
}
#JsonProperty("quotes")
public List<Quote> getQuotes() {
return quotes;
}
#JsonProperty("quotes")
public void setQuotes(List<Quote> quotes) {
this.quotes = quotes;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
But when I open the Quote class I am unable to access any of the properties
public class Quote {
#JsonProperty("id")
private Integer id;
#JsonProperty("dialogue")
private Boolean dialogue;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
* No args constructor for use in serialization
*
*/
public Quote() {
}
#JsonProperty("id")
public Integer getId() {
return id;
}
#JsonProperty("id")
public void setId(Integer id) {
this.id = id;
}
#JsonProperty("dialogue")
public Boolean getDialogue() {
return dialogue;
}
#JsonProperty("dialogue")
public void setDialogue(Boolean dialogue) {
this.dialogue = dialogue;
}
I tried using
listQuoteBodyResponse.body().getQuotes() but that only returned random numbers and when I tried using the Quote class for the response directly like
QuoteResponse.body.getDialogue() its just returning null
I was trying to add data to my tableView in my JavaFX app. I am using hibernate to do operations on my Database. I used a query to get all the orders and store each order in an object and added the object to the observable list of the tableView. I created the orders class and mapped it to my database. This is the class of the orders:
#Entity
#Table(name = "orders")
public class orders implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "order_id")
private int order_id;
#JoinColumn(name = "item_id")
#ManyToOne
#NotNull
private items item_id;
#Column(name = "quantity")
#NotNull
private int quantity;
#Column(name = "price_per_unit")
#NotNull
private double price_per_unit;
#Column(name = "total_price")
#NotNull
private double total_price;
#Column(name = "order_date")
#NotNull
private Date order_date;
#JoinColumn(name = "user_id")
#ManyToOne
#NotNull
private users user_id;
public orders() {
}
public orders(int order_id, items item_id, int quantity, double price_per_unit, double total_price, Date order_date, users user_id) {
this.order_id = order_id;
this.item_id = item_id;
this.quantity = quantity;
this.price_per_unit = price_per_unit;
this.total_price = total_price;
this.order_date = order_date;
this.user_id = user_id;
}
public int getOrder_id() {
return order_id;
}
public void setOrder_id(int order_id) {
this.order_id = order_id;
}
public items getItem_id() {
return item_id;
}
public void setItem_id(items item_id) {
this.item_id = item_id;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public double getPrice_per_unit() {
return price_per_unit;
}
public void setPrice_per_unit(double price_per_unit) {
this.price_per_unit = price_per_unit;
}
public double getTotal_price() {
return total_price;
}
public void setTotal_price(double total_price) {
this.total_price = total_price;
}
public Date getOrder_date() {
return order_date;
}
public void setOrder_date(Date order_date) {
this.order_date = order_date;
}
public users getUser_id() {
return user_id;
}
public void setUser_id(users user_id) {
this.user_id = user_id;
}
}
And the below code is the code of the view in which I have the tableView that loads the orders and displays the orders from the database:
public class OrdersPageController implements Initializable {
private Main app;
private Session session;
private Transaction transaction = null;
#FXML
private TableView<orders> table;
public void setApp(Main app) {
this.app = app;
}
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
session = HibernateUtil.getSessionFactory().openSession();
transaction = session.beginTransaction();
//Fill the table view
getOrders();
}
public void goBack(ActionEvent event){
session.close();
transaction = null;
app.goToHomePage();
}
public void processLogout(ActionEvent event){
session.close();
transaction = null;
app.userLogout();
}
public void addOrder(ActionEvent event){
session.close();
transaction = null;
app.addOrdersPage();
}
public void deleteOrder(ActionEvent event){
session.close();
transaction = null;
app.closeOrdersPage();
}
public void getOrders(){
try{
String hql = "FROM orders";
Query query = session.createQuery(hql);
List<orders> list = query.getResultList();
for (orders o : list) {
//Create an order object
orders order = new orders();
order.setOrder_id(o.getOrder_id());
order.setItem_id(o.getItem_id());
order.setPrice_per_unit(o.getPrice_per_unit());
order.setQuantity(o.getQuantity());
order.setOrder_date(o.getOrder_date());
order.setTotal_price(o.getTotal_price());
order.setUser_id(o.getUser_id());
//Create an observable list for the table
ObservableList<orders> tableList = table.getItems();
//Add the order object to the list
tableList.add(order);
//Set the created list to the table to show data
table.setItems(tableList);
}
}catch(Exception e){
System.out.println(e.getMessage());
}
finally{
session.close();
}
}
}
Note that the getOrders method is the method that gets the orders from the database and sets the observable list of the tableView.
I am having problem displaying the item_id and the user_id of the order. I think the problem is that they both are objects of type items and users respectively and the table displays the address of the objects. Instead I want to display the numbers of the ids of the item ordered and the user that made the order. If you know what I can do to fix my problem please share it with me.
Add cellFactorys to the relevant columns. You haven't shown the FXML in the question, so I don't know the names you assigned to the appropriate TableColumn instances, but you can do something like this:
public class OrdersPageController implements Initializable {
// ...
#FXML
private TableView<orders> table;
#FXML
private TableColumn<orders, users> userColumn ;
#Override
public void initialize(URL url, ResourceBundle rb) {
userColumn.setCellFactory(tc -> new TableCell<>() {
#Override
protected void updateItem(users user, boolean empty) {
super.updateItem(user, empty);
if (empty || user == null) {
setText("");
} else {
String text = /* anything you need based on user */
setText(text);
}
}
});
session = HibernateUtil.getSessionFactory().openSession();
transaction = session.beginTransaction();
//Fill the table view
getOrders();
}
}
Just override toString method in users and items Classes:
Example: in your users Class ->
#Override
public String toString() {
return user_id.toString();
}
As James_D stated, have a look on java conventions. Java Classes should be always be with Capital Letter.
So the thing that i want to happen, is making the tableview update the data in the database after editing it. I wanted to use the SetOnEditCommit method here. The cell editing does work, but it never gets updated, with no error either. In the first place im a bit clueless if this method is actually efficient (probably not), since its hard to find some sources for this specific thing. And the sources that i found weren't really helpful. So it would be nice if someone had an idea as to why it doesn't update, or maybe provide an alternate option here.
The mentioned part:
columnType.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<UserDetails, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<UserDetails, String> event) {
updataData();
}
});
tableview.setItems(null);
tableview.setItems(data);
}
public void updataData() {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://37.128.148.113:3306/FYS", "FYS", "Kcj8g87~");
Statement con = connection.createStatement();
//connection
TablePosition pos = tableview.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
TableColumn col = pos.getTableColumn();
String data1 = (String) col.getCellObservableValue(row).getValue();
//cell
UserDetails row1 = tableview.getSelectionModel().getSelectedItem();
c1 = row1.getId();
//row
//tableview variables
con.execute("UPDATE gevonden_bagage SET type = 'data1' WHERE koffer_id = 'c1' ");
//Query
} catch (SQLException ex) {
System.err.println("Error" + ex);
}
}
//get connection, get celldata, get id data from first row, update cell with selected id
full controller class:
package simple;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
/**
*
* #author admin
*/
public class FXMLUserController extends SimpleController implements Initializable {
#FXML
public TableView<UserDetails> tableview;
#FXML
public TableColumn<UserDetails, String> columnId;
#FXML
public TableColumn<UserDetails, String> columnType;
#FXML
public TableColumn<UserDetails, String> columnKleur;
#FXML
public TableColumn<UserDetails, String> columnLuchthaven;
#FXML
public TableColumn<UserDetails, String> columnKenmerken;
#FXML
public TableColumn<UserDetails, String> columnStatus;
#FXML
public TableColumn<UserDetails, String> columnDatum;
#FXML
private Button btnLoad;
//declare observable list for database data
private ObservableList<UserDetails> data;
private DbConnection dc;
String c1;
#FXML
//strings for getRow method
#Override
public void initialize(URL url, ResourceBundle rb) {
dc = new DbConnection();
loadDataFromDatabase();
}
#FXML
public void loadDataFromDatabase() {
try {
Connection conn = dc.Connect();
data = FXCollections.observableArrayList();
// Execute query and store result in a resultset
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM gevonden_bagage");
while (rs.next()) {
//get strings
data.add(new UserDetails(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5),
rs.getString(6), rs.getString(7)));
}
} catch (SQLException ex) {
System.err.println("Error" + ex);
}
//Set cell values to tableview.
tableview.setEditable(true);
tableview.getSelectionModel().setCellSelectionEnabled(true);
columnType.setCellFactory(TextFieldTableCell.forTableColumn());
columnKleur.setCellFactory(TextFieldTableCell.forTableColumn());
columnLuchthaven.setCellFactory(TextFieldTableCell.forTableColumn());
columnKenmerken.setCellFactory(TextFieldTableCell.forTableColumn());
columnStatus.setCellFactory(TextFieldTableCell.forTableColumn());
columnDatum.setCellFactory(TextFieldTableCell.forTableColumn());
//makes columns editable
columnId.setCellValueFactory(new PropertyValueFactory<>("id"));
columnType.setCellValueFactory(new PropertyValueFactory<>("type"));
columnKleur.setCellValueFactory(new PropertyValueFactory<>("kleur"));
columnLuchthaven.setCellValueFactory(new PropertyValueFactory<>("luchthaven"));
columnKenmerken.setCellValueFactory(new PropertyValueFactory<>("kenmerken"));
columnStatus.setCellValueFactory(new PropertyValueFactory<>("status"));
columnDatum.setCellValueFactory(new PropertyValueFactory<>("datum"));
columnType.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<UserDetails, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<UserDetails, String> event) {
updataData();
}
});
tableview.setItems(null);
tableview.setItems(data);
}
public void updataData() {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://37.128.148.113:3306/FYS", "FYS", "Kcj8g87~");
Statement con = connection.createStatement();
//connection
TablePosition pos = tableview.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
TableColumn col = pos.getTableColumn();
String data1 = (String) col.getCellObservableValue(row).getValue();
//cell
UserDetails row1 = tableview.getSelectionModel().getSelectedItem();
c1 = row1.getId();
//row
//tableview variables
con.execute("UPDATE gevonden_bagage SET type = 'data1' WHERE koffer_id = 'c1' ");
//Query
} catch (SQLException ex) {
System.err.println("Error" + ex);
}
}
//get connection, get celldata, get id data from first row, update cell with selected id
#FXML
public void getRow() {
TablePosition pos = tableview.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
TableColumn col = pos.getTableColumn();
// this gives the value in the selected cell:
String data1 = (String) col.getCellObservableValue(row).getValue();
System.out.println(data1);
//CURRENTLY UNUSED METHOD
}
}
Model class:
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
*
* #author admin
*/
public class UserDetails {
private final StringProperty id;
private final StringProperty type;
private final StringProperty kleur;
private final StringProperty luchthaven;
private final StringProperty kenmerken;
private final StringProperty status;
private final StringProperty datum;
//Default constructor
public UserDetails(String id, String type, String kleur, String luchthaven, String kenmerken, String status, String datum) {
this.id = new SimpleStringProperty(id);
this.type = new SimpleStringProperty(type);
this.kleur = new SimpleStringProperty(kleur);
this.luchthaven = new SimpleStringProperty(luchthaven);
this.kenmerken = new SimpleStringProperty(kenmerken);
this.status = new SimpleStringProperty(status);
this.datum = new SimpleStringProperty(datum);
}
//getters
public String getId() {
return id.get();
}
public String getType() {
return type.get();
}
public String getKleur() {
return kleur.get();
}
public String getLuchthaven() {
return luchthaven.get();
}
public String getKenmerken() {
return kenmerken.get();
}
public String getStatus() {
return status.get();
}
public String getDatum() {
return datum.get();
}
//setters
public void setId(String value) {
id.set(value);
}
public void setType(String value) {
type.set(value);
}
public void setKleur(String value) {
kleur.set(value);
}
public void setLuchthaven(String value) {
luchthaven.set(value);
}
public void setKenmerken(String value) {
kenmerken.set(value);
}
public void setStatus(String value) {
status.set(value);
}
public void setDatum(String value) {
datum.set(value);
}
//property values
public StringProperty idProperty() {
return id;
}
public StringProperty typeProperty() {
return type;
}
public StringProperty kleurProperty() {
return kleur;
}
public StringProperty luchthavenProperty() {
return luchthaven;
}
public StringProperty kenmerkenProperty() {
return kenmerken;
}
public StringProperty statusProperty() {
return status;
}
public StringProperty datumProperty() {
return datum;
}
}
From the TableView documentation:
By default the TableColumn edit commit handler is non-null, with a
default handler that attempts to overwrite the property value for the
item in the currently-being-edited row. It is able to do this as the
Cell.commitEdit(Object) method is passed in the new value, and this is
passed along to the edit commit handler via the CellEditEvent that is
fired. It is simply a matter of calling
TableColumn.CellEditEvent.getNewValue() to retrieve this value.
It is very important to note that if you call
TableColumn.setOnEditCommit(javafx.event.EventHandler) with your own
EventHandler, then you will be removing the default handler. Unless
you then handle the writeback to the property (or the relevant data
source), nothing will happen.
So the problem is that by setting the onEditCommit on columnType, you remove the default handler that actually updates typeProperty in the UserDetails instance. Consequently
String data1 = (String) col.getCellObservableValue(row).getValue();
gives the old value, and your update to the database won't change anything.
Additionally, you have errors in the way you create the SQL statement. You are making the id in the WHERE clause the literal value 'c1' (instead of the value contained in the variable c1, and similarly setting the value of type to the literal value 'data1', instead of the value in the variable data1.
Here is a fix, along with some simplification of the code and some better practices for avoiding SQL injection attacks:
columnType.setOnEditCommit(event -> {
UserDetails user = event.getRowValue();
user.setType(event.getNewValue());
updateData("type", event.getNewValue(), user.getId());
});
and then
private void updateData(String column, String newValue, String id) {
// btw it is way better to keep the connection open while the app is running,
// and just close it when the app shuts down....
// the following "try with resources" at least makes sure things are closed:
try (
Connection connection = DriverManager.getConnection("jdbc:mysql://37.128.148.113:3306/FYS", "FYS", "Kcj8g87~");
PreparedStatement stmt = connection.prepareStatement("UPDATE gevonden_bagage SET "+column+" = ? WHERE koffer_id = ? ");
) {
stmt.setString(1, newValue);
stmt.setString(2, id);
stmt.execute();
} catch (SQLException ex) {
System.err.println("Error");
// if anything goes wrong, you will need the stack trace:
ex.printStackTrace(System.err);
}
}
i had problem to read all date from db PostgreSQL and jpa/hibernate ejb
my table has array field see below :
#Entity
public class MyTable{
private Long id;
private String name;
private String[] values;
#Type(type = "com.usertype.StringArrayUserType")
public String[] getValues(){
return values;
}
public void setValues(String[] values){
this.values = values;
}
}
and user type class like this :
package com.almasprocess.model.bl.en;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.*;
public class StringArrayUserType implements UserType {
protected static final int[] SQL_TYPES = { Types.ARRAY };
#Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return this.deepCopy(cached);
}
#Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
#Override
public Serializable disassemble(Object value) throws HibernateException {
return (String[]) this.deepCopy(value);
}
#Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == null) {
return y == null;
}
return x.equals(y);
}
#Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
#Override
public boolean isMutable() {
return true;
}
#Override
public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
if (resultSet.wasNull()) {
return null;
}
if(resultSet.getArray(names[0]) == null){
return new Integer[0];
}
Array array = resultSet.getArray(names[0]);
String[] javaArray = (String[]) array.getArray();
return javaArray;
}
#Override
public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
Connection connection = statement.getConnection();
if (value == null) {
statement.setNull(index, SQL_TYPES[0]);
} else {
String[] castObject = (String[]) value;
Array array = connection.createArrayOf("varchar", castObject);
statement.setArray(index, array);
}
}
#Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
#Override
public Class<String[]> returnedClass() {
return String[].class;
}
#Override
public int[] sqlTypes() {
return new int[] { Types.ARRAY };
}
}
and read date like this in ejb class :
public List readMailBank(){
String query = "select mt from mytable mt";
TypedQuery<StringArrayUserType> typedQuery = em.createQuery(query , StringArrayUserType.class);
List<StringArrayUserType> results = typedQuery.getResultList();
return results;
}
or like this sample code :
public List readMailBank(){
Type stringType = (Type) new TypeLocatorImpl(new TypeResolver()).custom(StringArrayUserType.class);
Query query = em.createNativeQuery("select mt from mytable mt");
query.unwrap(SQLQuery.class).addScalar("mb", (org.hibernate.type.Type) stringType);
List<Mailbank>results = query.getResultList();
return results;
}
but i had this error :
Caused by: java.lang.IllegalArgumentException: Type specified for TypedQuery [com.usertype.StringArrayUserType] is incompatible with query return type [class [Ljava.lang.String;]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.resultClassChecking(AbstractEntityManagerImpl.java:387) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:344) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.jboss.as.jpa.container.AbstractEntityManager.createQuery(AbstractEntityManager.java:131) [wildfly-jpa-8.2.0.Final.jar:8.2.0.Final]
please help me to read all data from db and fills array in to my array field?
thanks
I think the problem with your first example is that you try to create your query for values in Java which is a String[], but your JPQL asks for MyTable values. Which classes are not extending each other, thus you get an exception about the type incompatibility.
Something like
select mt.values from mytable mt
should give you what you want. (If it doesn't work at once, here is some documentation about selecting values instead of entities.)
I have two entities as below and when i try to persist "Category" the "Tip" object list does not get persisted .I noticed that in my DAO class that I was able to see the category object with tipsForCategory list of size 1 but when i try to retrieve after persisting I am able to see only Category details and tipsForCategory comes as empty list.
#Entity
public class Category {
#GeneratedValue
#Id
public Long id;
#Column
public String categoryName;
#OneToMany(mappedBy = "category",cascade = {CascadeType.ALL})
public List<Tip> tipsForCategory;
public Long getId() { return id; }
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName.toLowerCase();
}
public void addTip(Tip tip) {
if(!tipsForCategory.contains(tip)) {
tipsForCategory.add(tip);
}
}
public List<Tip> getTipsForCategory() {
return tipsForCategory;
}
}
Code for Tip Entity
#Entity
public class Tip {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Key key;
#Column
public String tipDescription;
#ManyToOne(cascade = {CascadeType.ALL})
public Category category;
public String getTipDescription() {
return tipDescription;
}
public void setTipDescription(String tipInformation) {
this.tipDescription = tipInformation;
}
}
Code for persisting in my DAO
#Override
#Transactional
public void save(Category category) {
EntityManager localEntityManager=entityManager.getEntityManagerFactory().createEntityManager();
EntityTransaction transaction=localEntityManager.getTransaction();
try {
transaction.begin();
localEntityManager.persist(category);
localEntityManager.flush();
transaction.commit();
}catch (Exception e) {
e.printStackTrace();
localEntityManager.close();
}
}
My retrieval method is
#Override
public CategoryDTO findCategory(Long categoryId) throws FixitException{
CategoryDTO categoryDTO=null;
Category category=categoryDAO.findById(categoryId);
if(category!=null) {
categoryDTO=new CategoryDTO(category);
}
return categoryDTO;
}
#Override
public List<TipDTO> retrieveTips(Long categoryId) throws FixitException{
List<TipDTO> tips=null;
try {
CategoryDTO category = findCategory(categoryId);
if (category != null) {
tips = category.getTipsForCategory();
}
}
catch(Exception e)
{
throw new FixitException(FixitConstants.TIP_RETRIEVAL_ERROR+categoryId,e.getCause());
}
return tips;
}
Looks like the problem was with lazy fetch I just resolved the same.In my categoryDAO.findById(..) code I had to add an additional line to retrieve the tips as below
#Override
public Category findById(Long categoryId) {
Category category=null;
try {
TypedQuery<Category> findByCategoryId = entityManager.createQuery("Select cat from Category cat where cat.id=:categoryId",Category.class);
category=findByCategoryId.setParameter("categoryId", categoryId).getSingleResult();
}
catch (Exception e)
{
e.printStackTrace();
}
*** int tipsSize=category.getTipsForCategory().size();***
return category;
}