Hibernate. How to get non-uniform the tree from result? - java

I have a fairly simple problem. I need to get likeness a tree from the result of the stored procedure. But unfortunately all the examples I've found, used or tables, or uniform structure of the tree.
Stored procedure can return:
| firm_id | index_id | value |
| 1 | 101 | 123 |
| 1 | 102 | 123 |
| 2 | 101 | 123 |
I'm trying to divide by class:
#Entity
#NamedNativeQuery(
name = "getReport",
resultClass = Report.class,
query = "{call myProc(?)}",
callable = true
)
public class Report {
#Id
#Column(name = "firm_id")
private long firmId;
#Embedded
private List<Index> indexList;
// getters and setters
}
Second class:
#Embeddable
public class Index {
#Column(name = "index_id")
private long indexId;
#Column(name = "value")
private int value;
// getters and setters
}
As a result I get a null. I also tried using #ManyToOne/#OneToMany, but received "Table not found". What am I doing wrong?
Thank you for your attention.

Related

I am trying to connect 2 tables to have same rev number using hibernate envers?

I have customer entity that have List of accounts and each entity have audited tables,so tables generated will be :
(CUSTOMERS
,ACCOUNTS
,CUSTOMERS_AUD
,ACCOUNTS_AUD)
how can I connect the change of accounts with the change of customer in one rev number? hibernate envers gives separated version (rev number) for each table ?
The generated tables of my code:
CUSTOMERS_AUD TABLE
| ID | REV | REVTYPE |name |account_num|ACCOUNTID|
|:----|------:|:-------:|:----:|:---------:|:-------:|
| 1 | 1 | 0 |Ann |1234567897 |1 |
| 1 | 3 | 1 |Alex |1234567897 |1 |
| 1 | 5 | 1 |Alex |7777777777 |1 |
ACCOUNTS_AUD TABLE
| ID | REV | REVTYPE |name |account_num|
|:-----------|------:|:-------:|:----:|:---------:|
| 1 | 2 | 0 |Ann |1234567897 |
| 1 | 4 | 1 |Alex |7777777777 |
SAMPLE ENTITIES
#Entity
#Table(name="CUSTOMERS")
#Audited
public class Customer implements Serializable {
.
.
#ManyToOne
#org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.REPLICATE)
#JoinColumn(name="ACCOUNTNUMBERCOMBOBOXID", nullable=true)
private Account accountNumberComboBox;
public static final String REF_CUSTOMERS_ACCOUNTS = "refCustomersAccounts";
#OneToMany(mappedBy = "refCustomers")
#org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.REPLICATE)
private List<Account> refCustomersAccounts;
.
.
.
}
#Entity
#Table(name="ACCOUNTS")
#Audited
public class Account implements Serializable {
.
.
public static final String REF_CUSTOMERS = "refCustomers";
#ManyToOne
#org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.REPLICATE)
#JoinColumn(name="REFCUSTOMERSID", nullable=true)
private Customer refCustomers;
.
.
.
}
THE RESULTS THAT I WANT
CUSTOMERS_AUD TABLE
| ID | REV | REVTYPE |name |account_num|ACCOUNTID|
|:----|------:|:-------:|:----:|:---------:|:-------:|
| 1 | 1 | 0 |Ann |1234567897 |1 |
| 1 | 2 | 1 |Alex |1234567897 |1 |
| 1 | 3 | 1 |Alex |7777777777 |1 |
ACCOUNTS_AUD TABLE
| ID | REV | REVTYPE |name |account_num|
|:-----------|------:|:-------:|:----:|:---------:|
| 1 | 1 | 0 |Ann |1234567897 |
| 1 | 2 | 0 |Ann |1234567897 |
| 1 | 3 | 1 |Alex |7777777777 |
Spring boot application
#SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
#Autowired
private ApplicationContext context;
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
CustomerRepo customerRepo = context.getBean(CustomerRepo.class);
AccountRepo accountRepo = context.getBean(AccountRepo.class);
AccountTypeRepo accountTypeRepo = context.getBean(AccountTypeRepo.class);
Accounts account = new Accounts();
Customers customer = new Customers();
customer.setId(1L);
account.setId(1L);
account.setFromDate(new Date());
account.setToDate(new Date());
account.setNewAcountNumber("1234567897");
account.setOwner("Ann");
customer.setAccountNumber(account.getNewAcountNumber());
customer.setCode("CODE");
customer.setName(account.getOwner());
customer.setFromDate(new Date());
customer.setToDate(new Date());
customer.setAccountNumberComboBox(account);
accountRepo.save(account);
customerRepo.save(customer);//0
customer.setName("Alex");
customerRepo.save(customer);//1
account.setNewAcountNumber("7777777777");
accountRepo.save(account);
}
}
Account Repo
#Repository
public interface AccountRepo extends CrudRepository<Accounts,Long> {
}
Customer Repo
#Repository
public interface CustomerRepo extends CrudRepository<Customers, Long> {
}
The revision number is associated with the transaction, so whatever operations you perform in a single transaction will be audited and stored with the same revision number, always.
Since you did not show your persistence code I can only guess at this point that the code is likely saving the Customer entity in one transaction and in a subsequent transaction you're saving the Account entity.
If you save them both within the same transaction, they'll get the same revision number assigned to their audit rows.

Reading XML and Creating Multiple Tables

I have an XML input file that looks like:
<mbean className="OperatingSystem">
<attribute>
<attributeName>Arch</attributeName>
<formatter>STRING</formatter>
</attribute>
<attribute>
<attributeName>ProcessCpuLoad</attributeName>
<formatType>PERCENT</formatType>
</attribute>
</mbean>
I've created a POJO called 'Mbeans' that looks like:
#XmlRootElement(name = "mbean")
#XmlAccessorType(XmlAccessType.FIELD)
public class Mbean
{
#XmlElement(name = "attribute")
private List<Attribute> attributes = null;
#XmlAttribute(name = "className")
private String className;
public String getClassName() {
return className;
}
}
I can successfully unmarshall my XML File into this POJO and my application can use this object as needed. This input file tells me the information I need to pull from a particular MBean I have. Is there a way to create multiple tables based on the XML file, such that when I pull said information I can store that information into said table structure and then use JDBC to create SQL tables on my H2 database?
For example, I would like to create tables that look like:
+------------------------+
| MBeans |
+------+-----------------+
| ID | MBeanName |
+------+-----------------+
| 1 | OperatingSystem |
+------+-----------------+
+--------------------------------+
| Attributes |
+------+--------+----------------+
| ID | MbeanId| AttributeName |
+------+--------+----------------+
| 1 | 1 | Arch |
+------+--------+----------------+
| 2 | 1 | ProcessCpuLoad |
+------+--------+----------------+
+------------------------------------+
| OperatingSystem.Arch |
+------+--------+------------+-------+
| ID | MbeanId| AttributeId| Value |
+------+--------+------------+-------+
| 1 | 1 | 1 | amd64 |
+------+--------+------------+-------+
| 2 | 1 | 1 | amd64 |
+------+--------+------------+-------+
+------------------------------------+
| OperatingSystem.ProcessCpuLoad |
+------+--------+------------+-------+
| ID | MbeanId| AttributeId| Value |
+------+--------+------------+-------+
| 1 | 1 | 2 | 0.009 |
+------+--------+------------+-------+
| 2 | 1 | 2 | 0.0691|
+------+--------+------------+-------+
I would first make :
A method mapping className into table name public String getTableName(String className)
A method mapping attributeName into clomun name public String getColumnName(String attributeName)
A method mapping formatType or formatter into the database types public String getType(String formatType)
and then
public void createTable(Mbean bean) throws SQLException{
String sql = getCreateTable(bean);
// execute SQL using JDBC...
}
private String getCreateTable(Mbean bean) {
String sqlStart = "CREATE TABLE " + getTableName(bean.getClassName()) + " (" ;
return bean.getAttributes().stream()
.map(attribute -> mapToColumn(attribute))
.collect(Collectors.joining(", ", sqlStart, ")"); // what about primary key?
}
private String mapToColumn(Attribute a) {
return getColumnName(a.getName()) + " " + getType(/*it depends*/);
}

Spring,Hibernate with mysql image is not displaying properly

Yesterday I have posted this question..But did not get any answer.
In my project I have stored image file in mysql database.
the table is like:
+-----------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+----------------+
| upload_id | int(11) | NO | PRI | NULL | auto_increment |
| uId | int(20) unsigned | NO | MUL | NULL | |
| file_name | varchar(128) | YES | | NULL | |
| file_data | longblob | YES | | NULL | |
+-----------+---------------------+------+-----+---------+----------------+
Now I am fetching image data my dao class is:--
public List<ImageClass> fetchallimage(int uId) {
ImageClass imageClass= new ImageClass(uId);
String hql = "FROM ImageClass WHERE uId = :uId1 ";
Query query = (Query) sessionFactory.getCurrentSession().createQuery(hql).setParameter("uId1", imageClass.getUserId());
return query.list();
}
My ImageClass is:--
#Table(name = "imageStore")
public class ImageClass{
private long id;
private String fileName;
private byte[] data;
---getters and settrs with #Column annotations----
}
My controller class is:-
#RequestMapping(method = RequestMethod.GET)
public String ImageFetch(Map<String, Object> map,HttpServletRequest request,
HttpSession session,HttpServletResponse response) {
int uid= (int) session.getAttribute("uId");
List<ImageClass> imageClass;
imageClass= PicService.fetchallimage(uid);
map.put("image",imageClass);
return "account";
}
}
and jsp page is:-
<c:forEach items="${image}" var="info">
<div style="width:380px;display:block;text-align:center;">
<img src="${info.data}"
border="0" alt="Dating" style="margin:10px;padding:15px;border:10px solid #FEB4DE;background:#FECDE9;"></div>
</c:forEach>
But the picture is displaying,like below:-
In page image looks like: [B#1284b24
why??what I have to do to achieve the image??Please guys suggest me.
I have edited :--
for (ImageClass temp : imageClass) {
byte[] encodeBase64 = Base64.encode(temp.getData());
String base64Encoded = new String(encodeBase64, "UTF-8");
map.put("image",base64Encoded); }
and in jsp :--<img src="data:image/jpeg;base64,${image}" />
still not getting picture.
in logger I am getting output:--
You have to convert that imageTo String and then you can easily display in JSP. I presume its a byte[]. Use a #Transient variable, it will help :
import sun.misc.BASE64Encoder;
BASE64Encoder base64Encoder = new BASE64Encoder();
object.setTransientString("data:image/png;base64," + base64Encoder.encode(object.getByteArrayDataVariable()));
In jsp, use the img tag and put the String variable there. Enjoy.

Getting data from cursor and store it in string array

ID| TOPIC | TITLE | TYPE | NAME |
---------------------------------
1 | AB | BCD | ref | Ferari|
----------------------------------
1 | AB | BCD | ref | TOYOTA|
----------------------------------
1 | AB | BCD | ref| AUDI |
----------------------------------
1 | AB | BCD | ref| BMW |
---------------------------------
2 | BC | ABC | ref | NISSAN|
----------------------------------
2 | BC | ABC | ref | SUZKI|
----------------------------------
2 | BC | ABC | ref| TATA |
Cursor hold data like this table. Now, I want get data like ID| TOPIC | TITLE | TYPE | NAME | here NAME can be multiple according to the ID. Like for ID 1 K will be FERARI,TOYOTA,AUDI,BMW and so on. I want to show this information in customlistview in a row .
My question is
is there any way to store the name data in String Array or do you have any alternative suggestion for me
If I understand your question correctly, you want to store your values from your database table in arrays? For that, you could create parallel resizeable generic lists like this:
ArrayList<int> ids = new ArrayList<int>();
ArrayList<String> topics = new ArrayList<String>();
ArrayList<String> titles = new ArrayList<String>();
ArrayList<String> types = new ArrayList<String>();
ArrayList<String> names = new ArrayList<String>();
And you can then add items to it like this:
ids.add(cursor.getInt(cursor.getColumnIndexOrThrow("_id")));
topics.add(cursor.getString(cursor.getColumnIndexOrThrow("TOPIC")));
titles.add(cursor.getString(cursor.getColumnIndexOrThrow("TITLE")));
types.add(cursor.getString(cursor.getColumnIndexOrThrow("TYPE")));
names.add(cursor.getString(cursor.getColumnIndexOrThrow("NAME")));
P.S. your database looks wrong - values in ID column should be unique, if ID is the primary key (it looks like it should be).
P.S.P.S
Another option would be to use Object-Oriented design - Create a class that has members like id, topic, title, type, name and so on.
public class Product {
private int id;
private String topic;
private String title;
private String type;
private String name;
public Product(Cursor cursor) {
this.id = cursor.getInt(cursor.getColumnIndexOrThrow("_id"));
this.topic = cursor.getString(cursor.getColumnIndexOrThrow("TOPIC"));
this.title = cursor.getString(cursor.getColumnIndexOrThrow("TITLE"));
this.type = cursor.getString(cursor.getColumnIndexOrThrow("TYPE"));
this.name = cursor.getString(cursor.getColumnIndexOrThrow("NAME"));
}
//Getter & Setter here...
}
this Product could be in a list of Products like:
ArrayList<Product> products = new ArrayList<Product>();
Product product = new Product(cursor);
products.add(product); // or simpler: products.add(new Product(cursor);
and you could use this list for many purposes like:
ArrayList<int> ids = new ArrayList<int>();
ArrayList<String> topics = new ArrayList<String>();
ArrayList<String> titles = new ArrayList<String>();
ArrayList<String> types = new ArrayList<String>();
ArrayList<String> names = new ArrayList<String>();
for (Product product : products) {
// for every product in your products list do:
ids.add(product.getId);
topics.add(product.getTopic);
titles.add(product.getTitle);
types.add(product.getType);
names.add(product.getName);
}

Getting repeated entries in table on a one-to-many relation

I'm learning jpa and decided to do a basic webapp where a User can post Messages, so a user have many messages. The problem is that when I add a message to the User's messages collection, I get duplicated entries in the Message table. (note I have two tables with the owner Id on Message, there is no join table).
This is the conversation:
First message -> Larry says: Hello John
Second message -> Larry says: Are you there?
Third Message -> John says: Yep
Fourth Message -> Larry says: ok
Fifth Message -> John says: fine
This is what I get in the screen:
Larry: Hello John
Larry Hello John
Larry: Are you there?
John: Yep
Larry: Hello John
Larry: Are you there?
Larry: ok
John: Yep
John: fine
The table content is:
+----+----------------+----------+
| id | message | owner_id |
+----+----------------+----------+
| 1 | Hello John | NULL | <- Why the NULL fields?
| 2 | Hello John | NULL |
| 3 | Are you there? | NULL |
| 4 | Yep | NULL |
| 5 | Hello John | 1 |
| 6 | Are you there? | 1 |
| 7 | ok | 1 |
| 8 | Yep | 2 |
| 9 | fine | 2 |
+----+----------------+----------+
These are the classes I have and its mappings.
#Entity
public class User implements Serializable {
#Id
#GeneratedValue
private Long id;
private String username;
private String password;
#OneToMany (fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name="owner_id")
private List<Message> messages; ...and all of its corresponding getters and setters
#Entity
public class Message implements Serializable {
#Id
#GeneratedValue
private Long id;
private String message;
#ManyToOne
private User owner; //...and all of its corresponding getters and setters
This is the relevant jsp scriptlet section which saves the user:
User user = (User)session.getAttribute("user");
user.getMessages().add(new Message(request.getParameter("message")));
FactoryDAO.getInstance().getUserDAO().update(user);
update(user) method:
public void update(User user) {
initEntityManager(); <- method in the superclass which initializes the entityManager
tx.begin();
entityManager.merge(user);
entityManager.flush();
tx.commit();
closeEntityManager();
}
Can you help me to find out what is wrong here?
Thanks!
It might have something to do with the way you're creating new User objects (not shown in your code).
Other than that, a couple of things you could try:
Use persist and not merge in the update method
Use a Set instead of a List for storing messages
Be sure to override equals and hashCode in both of your entities
I fix the problem doing as follows:
<%
User user = (User)session.getAttribute("user");
Message message = new Message(request.getParameter("message"));
message.setOwner(user);
FactoryDAO.getInstance().getMessageDAO().update(message);
%>
I have set a owner to a message instead of a message to a user.
I still don't understand why my first version didn't work as I expected.

Categories

Resources