I am Hibernate newbie, and developing a servlet which gets its parameters from a URL, creates a Hibernate object, then stores it into a MySQL database.
I am sending 1000 URLs concurrently. When I look at the MySQL table, it adds only the last object to the database.
doGet method:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//HttpSession session = request.getSession(true);
//session.putValue("uid", count);
String id = request.getParameter("id");
String url = request.getParameter("url");
String lastVisitTime = request.getParameter("lastVisitTime");
String visitCount = request.getParameter("visitCount");
String title = request.getParameter("title");
String typedCount = request.getParameter("typedCount");
HistoryItem hi = new HistoryItem(id, url, lastVisitTime, visitCount, title, typedCount);
File f = new File("C:\\Users\\atılay\\Desktop\\apache-tomcat-7.0.30-windows-x64\\jspservlets\\UserModeling\\src\\hibernate.cfg.xml");
SessionFactory sessionFactory = new Configuration().configure(f).buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(hi);
session.getTransaction().commit();
session.flush();
session.close();
}
HistoryItem:
public class HistoryItem {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Basic(optional = false)
private int i;
private String id = "";
private String url = "";
private String lastVisitTime = "";
private String visitCount = "";
private String title = "";
private String typedCount = "";
}
What is the problem? I could not find any solution.
If you're creating an object/entity to be saved into the database, you shouldn't be setting it's ID.
Allocating the ID happens when the object is saved -- and this is Hibernate's responsibility. Having the ID already set, means HB considers the object has been saved already.
Really this is not a very good question, or coding style, or example.
'Sending 1000 URL concurrently'. What does that mean? You have 1000 browsers open at once, and send a request from all of them simultaneously? Talk sense.
Your SessionFactory should be kept in the webapp or servlet. This code is doing an entire Hibernate startup & initialization, for every page request.
File f = new File("C:\\Users\\atılay\\Desktop\\apache-tomcat-7.0.30-windows-x64\\jspservlets\\UserModeling\\src\\hibernate.cfg.xml");
SessionFactory sessionFactory = new Configuration().configure(f).buildSessionFactory();
Get rid of 'ID' as a parameter -- or else use it optionally, to load & edit records -- and do the Hibernate setup properly.
Then your project might work.
Related
I'm currently using db (mysql) to store my sessions with spring. It is generating new session id for each user but it is replacing session id's of previously who are logged. Please give some suggestions to overcome this problem.
The following the service which is I am calling from controller for each request
image1
image2
public class MultiLoginServiceImpl
{
public static String createMultiLogin(HttpServletRequest httpRequest)
{
String alias = httpRequest.getParameter("_s");
System.err.println("alias"+alias);
#SuppressWarnings("unchecked")
SessionRepository<Session> sessionRepository =(SessionRepository<Session>) httpRequest.getAttribute(SessionRepository.class.getName());
Map<String, String> sessionIds = sessionManager.getSessionIds(httpRequest);
System.out.println(sessionIds);
for(Map.Entry<String, String> entry : sessionManager.getSessionIds(httpRequest).entrySet()) {
String aliasId = entry.getKey();
String sessionId = entry.getValue();
HttpSession httpSession = httpRequest.getSession(false);
Session storedSession = sessionRepository.getSession(sessionId);
if(storedSession.getAttribute("userEmailId")!= null)
{
httpSession.setAttribute("userEmailId", storedSession.getAttribute("userEmailId"));
}
System.out.println("mapids"+aliasId +" : "+sessionId);
}
String addAlias = alias== null ? newSessionAlias1: requestedSessionAlias1;
/*if(alias == null || "".equals(alias.trim()))
{
alias = sessionManager.getNewSessionAlias(httpRequest);
}*/
httpRequest.setAttribute("alias",addAlias);
//SecurityContext context = (SecurityContext) httpSession.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
//System.out.println(context.toString());
String addAccountUrl = sessionManager.encodeURL(httpRequest.getContextPath(), addAlias);
System.out.println("addalias"+addAlias);
return addAccountUrl ;
}
}
I am currently using Firebase Authentication in my mobile app. The back end is a Spring boot application. The REST APIs on the back end relies on a token generated from Firebase Authentication to retrieve the Firebase UID (verifyIDToken method) of a user to perform further functions.
Currently, I notice that in Firebase Java API (server-based), there is no way of generating a token for a user, thus there is no easy way for me to do JUnit testing on the server that relies on user authentication. Anyone has clues on how to do so?
This is the sample code that does not work:
#RequestMapping(value = "/api/subscribeChannel/{channelid}", method = RequestMethod.GET, produces = "application/json")
public DeferredResult<Object> subscribeChannel(#PathVariable Long channelid,#RequestHeader(value=FIREBASETOKEN, required = true) String idToken) {
DeferredResult<Object> result = new DeferredResult<Object>(DEFERREDTIMEOUT);
// test it out with a locally generated token
idToken = FirebaseAuth.getInstance().createCustomToken("valid Uid");
Task<FirebaseToken> task = FirebaseAuth.getInstance().verifyIdToken(idToken)
.addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
#Override
public void onSuccess(FirebaseToken decodedToken) {
String uid = decodedToken.getUid();
logger.info("Subscribe channel on success");
// do something
ret.setStatus("success");
ret.setMessage("channel id " + channelid + " subscribed");
result.setResult(ret);
} else {
result.setErrorResult(retStatus.getMessage());
}
}
}) .addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(Exception arg0) {
Exception te = new TokenNotFoundException(idToken);
logger.error("Token Not Found for " + idToken);
result.setErrorResult(te);
}
});
return result;
}
The custom token you get is different from the ID token that you use to log on. To get an id token from a custom token, do this:
private static final String ID_TOOLKIT_URL =
"https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken";
private static final JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
private static final HttpTransport transport = Utils.getDefaultTransport();
private static final String FIREBASE_API_KEY = "<your api key here>";
private String signInWithCustomToken(String customToken) throws IOException {
GenericUrl url = new GenericUrl(ID_TOOLKIT_URL + "?key="
+ FIREBASE_API_KEY);
Map<String, Object> content = ImmutableMap.<String, Object>of(
"token", customToken, "returnSecureToken", true);
HttpRequest request = transport.createRequestFactory().buildPostRequest(url,
new JsonHttpContent(jsonFactory, content));
request.setParser(new JsonObjectParser(jsonFactory));
com.google.api.client.http.HttpResponse response = request.execute();
try {
GenericJson json = response.parseAs(GenericJson.class);
return json.get("idToken").toString();
} finally {
response.disconnect();
}
}
The Java API to generate custom tokens is documented under Create custom tokens using the Firebase SDK.
From there:
String uid = "some-uid";
String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
I have a simple JAX-RS 2 web service that contains a Customer entity, and the Customer may have zero or more Address entities associated with it. In our service's findAll() method, we want to just return the data in each Customer, without serializeing the Addresses. This is working perfectly.
In our find(long id) method, we want to return a specific customer with all of is Addresses. I have tried a million things, but cannot seem to get a Customer to serialize its Addresses. When I look in the debugger at the entity that is found by find() (code follows), it shows the List addressList as "(IndirectList) "size = 3", so I expected that the entire entity and list will be serialized, but it doesn't happen. We do have a writer interceptor (code follows) that is used to satisfy some specific requirements. In it, I call proceed(), so the entity is serialized by Jackson. After serialization, I look at the json string, and it only serialized the Customer... No addresses. I figured that I might need to force the loading of the addresses before serialization, so I called the getAddressList() method on the entity before proceed(), but it didn't help.
I am totally at a loss as to what I am doing wrong... I really would appreciate your help with this issue.
Thank you for your time and suggestions,
Mike
====================================================================
=========================== TECHNOLOGIES ===========================
====================================================================
NetBeans IDE 8.0 (Build 201403101706)
Java 1.8.0_11; Java HotSpot(TM) 64-Bit Server VM 25.11-b03
JPA2.1
JAX2
Jackson Json 2.4.2
GlassFish Server 4
MySQL Community Server 5.6.20 (ENGINE=InnoDB)
====================================================================
////////////////////////////////////////////////////////
// CUSTOMER CLASS
////////////////////////////////////////////////////////
#Entity
#Table(name = "customers")
#XmlRootElement
public class Customer implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#XmlAttribute(required=true)
#Column(name = "Id")
private Long id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "customerId", fetch = FetchType.LAZY)
private List<Address> addressList;
#XmlTransient
public List<Address> getAddressList() {
return addressList;
}
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
}
}
///////////////////////////////////////////////////
// FIND A CUSTOMER BY ID
///////////////////////////////////////////////////
// Query to find an entity by id.
protected T find(Object id) {
// Find the object
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> from = cq.from(entityClass);
javax.persistence.criteria.CriteriaQuery<T> select = cq.select(from);
cq.where(cb.equal(from.<T>get("id"), id));
javax.persistence.TypedQuery<T> tq = getEntityManager().createQuery(select);
return getSingleResultOrNull(tq);
}
///////////////////////////////////////////////////////////////
// WRITER INTERCEPTOR
///////////////////////////////////////////////////////////////
#Provider
public class MyWriterInterceptor implements WriterInterceptor {
#Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
final OutputStream originalStream = context.getOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
context.setOutputStream(baos);
try
{
// FORCE THE ADDRESS LIST TO LOAD BEFORE SERIALIZATION?
// IN THE DEBUGGER IT SHOWS DATA WITH "(IndirectList) "size = 3"
// THIS FORCING DID NOT MAKE THE COLLECTION SERIALIZE TO JSON.
Object entity = context.getEntity();
Customer customer = (Customer) entity;
// Force lazy load to be loaded.
customer.getAddressList().size();
context.proceed();
}
catch (Exception ex)
{
System.out.println(ex.getCause());
}
////////////////////////////////////////////////////////////////////////////
// Doing a scan of the generated json to meet some specific requirements...
////////////////////////////////////////////////////////////////////////////
// Write to and restore the original Stream.
baos.writeTo(originalStream);
baos.close();
context.setOutputStream(originalStream);
}
My application takes username and password and on clinking the hyperlinkbutton, these values are sent to the server and hence server returns something like PASS:ClientID. I wish to navigate to SecondPage.xaml (from MainPage.xaml.cs) only if the responseString contains PASS.
Here is my code:
namespace aquila1
{
public partial class MainPage : PhoneApplicationPage
{
static string username;
static string password;
static string rs;
static NavigationService ns = new NavigationService();
// Constructor
public MainPage()
{
InitializeComponent();
}
private static ManualResetEvent allDone = new ManualResetEvent(true);
private void HyperlinkButton_Click_1(object sender, RoutedEventArgs e)
{
username = textbox1.Text;
password = textbox2.Text;
System.Diagnostics.Debug.WriteLine(username);
System.Diagnostics.Debug.WriteLine(password);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://60.243.245.181/fms_tracking/php/mobile_login.php?username=" + username + "&password=" + password);
request.ContentType = "application/x-www-form-urlencoded";
// Set the Method property to 'POST' to post data to the URI.
request.Method = "POST";
// start the asynchronous operation
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
// Keep the main thread from continuing while the asynchronous
// operation completes. A real world application
// could do something useful such as updating its user interface.
allDone.WaitOne();
}
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
// Console.WriteLine("Please enter the input data to be posted:");
string postData = username + "+" + password;
System.Diagnostics.Debug.WriteLine(postData);
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Write to the request stream.
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
rs = responseString;
System.Diagnostics.Debug.WriteLine(responseString);
System.Diagnostics.Debug.WriteLine("#####");
System.Diagnostics.Debug.WriteLine(rs);
// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
move2();
allDone.Set();
}
private static void move2()
{
string[] rs1 = rs.Split(':');
if ((rs1[0].Trim()).Equals("PASS"))
{
ns.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));
}
else
{
MessageBox.Show(rs);
}
}
}
}
On running the code, i always get NullReferenceException .
Plz help me find the error and suggest corrections.
Thanks in advance
You're most likely getting the error because the NavigationService cannot find the resource /SecondPage.xaml. Is SecondPage located at the root of your project?
This can also be caused by trying to navigate before the target resource is loaded (for example, by navigating inside a page's constructor), but that doesn't immediately appear to be your problem.
This answer suggests that this problem can occur after changing namespaces or assembly names. It states that cleaning the project, ensuring all bin and obj folders are empty, then recompiling will fix it. However, its reference link is dead.
I met a weird problem with updating & displaying data in hibernate. Can anyone help me please!?
I am using hibernate, spring with mysql.
The problem here i am facing is, any changes can be applied to database. But if I load updated item on web page, it always returns the old data or new data randomly.
I am sure that it is not a problem of browser cache. I tried to print out return data in getPost method in dao class. It just print out wrong message sometimes.
Say, if I change post content for multiple times, all changes can be stored in database. But If I continuously refresh page to display changed data, it displays all previous changes randomly.
I have tried different ways to load data in getPost method, but still face same problem:
tried session.clear, and session.flush
close second level cache as :
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_structured_entries">false</prop>
different way to load data: session.load, session.get, hibernate query, Criteria, all have same issue.
In getPost method of postDAO: I tried to load data by native SQL first, and wanted to compare with result of hibernate query. both queries return old data.
Code:
public class Post implements Cloneable, Serializable {
private String postID;
private String content;
}
PostSelectController (controller):
public class PostSelectController extends AbstractController
{
....
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception
{
String id = request.getParameter("id");
Course course = null;
Vendor vendor = null;
Post post = null;
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName(getSuccessView());
post = postService.getPost(id);
modelAndView.addObject("post", post);
return modelAndView;
}
}
postService:
#Transactional(propagation=Propagation.SUPPORTS, isolation=Isolation.READ_COMMITTED, readOnly=true)
public class PostService
{
#Transactional(propagation=Propagation.REQUIRED, readOnly=false)
public boolean updatePost(Post post) {
System.out.println("service side::::::::::::::::::::::"+(post.getBestAnswer()!=null));
if(post.getBestAnswer()!=null) System.out.println(">>>>>>>>"+post.getBestAnswer().getPostID());
System.out.println("service side::::::::::::::::::::::"+(post.getBestAnswer()!=null));;
return this.postDAO.updatePost(post);
}
public Post getPost(String postID) {
return this.postDAO.getPost(postID);
}
}
postDAO:
public class PostDAO {
private SessionFactory sessionFactory;
...
public boolean updatePost(Post post) {
boolean proceed = true;
try {
Session session = sessionFactory.getCurrentSession();
session.merge(post); //tried session.update, same problem
session.flush(); //it does not help
} catch (Exception ex) {
logger.error(post.getPostID() + " refused :: " + ex.getMessage());
proceed = false;
}
return proceed;
}
public Post getPost(String postID) {
Session session = sessionFactory.getCurrentSession();
try{
PreparedStatement st = session.connection()
.prepareStatement("select content from post where postid='"+postID+"'") ;
ResultSet rs =st.executeQuery();
while (rs.next()) {
System.out.println("database::::::::::::::::::"+rs.getInt("content"));
// tried to use native sql to load data from database and compare it with result of hibernate query.
break;
}
}catch(Exception ex){
}
Criteria crit = session.createCriteria(Post.class);
NaturalIdentifier natId = Restrictions.naturalId();
natId.set("postID", postID);
crit.add(natId);
crit.setCacheable(false);
List<Post> posts = crit.list();
Post post = null;
if(posts!=null) post = posts.get(0);
System.out.println("hibernate::::::::::::::::::"+post.getContent());
return post;
}
I had the same trouble. The answer i found quikly. As Riccardo said the problem was in not cleanly closing session, so session was randomly recycled. i`ve done this in consructor of the class.
Ex(i used here HybernateUtil):
public yourHelper() {
this.session = HibernateUtil.getSessionFactory().getCurrentSession();
if (session.isOpen()){
session.close();
session=HibernateUtil.getSessionFactory().openSession();
}
}
code of HibernateUtil:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
System.out.println("SRPU_INFO: Initial SessionFactory creation success.");
} catch (Throwable ex) {
// Log the exception.
System.out.println("SRPU_INFO: Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
thanx for reading
Looks like you retrieve a list and display only the first entry of the list. I am guessing that the list is populated with more than one item, in random order each time, since there's no order-by criteria.Thus the first element of the list might differ for different executions.
Are you expecting a unique result ? If so, it would be better to use Criteria.uniqueResult();
It may depend on the way you obtain the session: if you are using the typycal HibernateUtil with ThreadLocal session it may be the case you are not correctly closing the session after you finish working with it. In this case the session in almost randomly recycled by completely unrelated units of work which will get the cached value