I'm having an issue with a JSON string in getting back from a FileInputStream in Java. I'm using Android. The problem is the string is not read in it's entirety and is cut off about half way through. I thought this might be to do with the max buffer size i have assigned maxBufferSize = 84 * 1024 in my UploadImage class, however if i increase that too much i get exception errors thrown when i attempt to read the byte stream. Here is my UploadImage class:
public class UploadImage {
public String serverUrl = "#";
public String filepath;
// Context allows for the access to application specific resources
Context context;
// json returned
public static String json_returned = "";
public UploadImage(String path, Context c) {
filepath = path;context = c;
}
public int uploadFile() {
String file = filepath;
int serverResponse = 200;
HttpURLConnection con = null;
DataOutputStream dos = null;
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
// TODO: This size may differ greatly on different devices. Plz Fix.
int maxBufferSize = 84 * 1024;
File sourceFile = new File(file);
Log.e("","SourceFile: "+sourceFile);
// check if the file exists
if(!sourceFile.isFile()) {
return 0;
} else {
try {
FileInputStream fileInput = new FileInputStream(sourceFile);
URL url = new URL(serverUrl);
// Open connection to send image
con = (HttpURLConnection)url.openConnection();
con.setDoInput(true); // Allow Inputs
con.setDoOutput(true); // Allow Outputs
con.setUseCaches(false);
con.setRequestMethod("POST");
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("ENCTYPE", "multipart/form-data");
con.setRequestProperty("Content-Type", "multipart/form-data;boundary=*****");
con.setRequestProperty("image_data", filepath);
// Now get our response/output stream from the server
dos = new DataOutputStream(con.getOutputStream());
dos.writeBytes("--*****\r\n");
dos.writeBytes("Content-Disposition: form-data; name='image_data';filename="+"'"
+ filepath + ".jpg'" + "\r\n");
dos.writeBytes("\r\n");
// Now read our file and then write to it
bytesAvailable = fileInput.available();
Log.e("", "BytesAvailable: "+bytesAvailable);
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInput.read(buffer, 0, maxBufferSize);
while(bytesRead > 0) {
dos.write(buffer,0,bufferSize);
bytesAvailable = fileInput.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInput.read(buffer,0,bufferSize);
}
dos.writeBytes("\r\n");
dos.writeBytes("--*****\r\n");
BufferedReader sr = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
StringBuilder responseString = new StringBuilder();
String inputStr;
while((inputStr = sr.readLine()) != null) {
responseString.append(inputStr);
}
GetResponse(responseString.toString());
// get server response
serverResponse = con.getResponseCode();
String response = con.getResponseMessage();
Log.i("image_data", "HTTP Response is : "
+ response + ": " + serverResponse);
// close the stream
fileInput.close();
dos.flush();
dos.close();
Log.e("End of Connection, ", "File apparently Uploaded.");
} catch(MalformedURLException ex) {
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
} catch(Exception e) {
//Log.e("Other Exception: ", "ex: "+e);
e.printStackTrace();
}
}
return serverResponse;
}
public void GetResponse(String response) {
if(!response.isEmpty()) {
this.json_returned = response;
}
}
public String getString() {
return json_returned;
}
}
The JSON string i should be expecting is this:
{
"foods":{
"food":[
{
"food_description":"Per 101g - Calories: 197kcal | Fat: 7.79g | Carbs: 0.00g | Protein: 29.80g",
"food_id":"1641",
"food_name":"Chicken Breast",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-breast-ns-as-to-skin-eaten"
},
{
"food_description":"Per 100g - Calories: 110kcal | Fat: 1.24g | Carbs: 0.00g | Protein: 23.09g",
"food_id":"4881229",
"food_name":"Skinless Chicken Breast",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-breast-skinless"
},
{
"food_description":"Per 101g - Calories: 239kcal | Fat: 13.60g | Carbs: 0.00g | Protein: 27.30g",
"food_id":"448901",
"food_name":"Grilled Chicken",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-grilled-ns-as-to-skin-eaten"
},
{
"food_description":"Per 101g - Calories: 247kcal | Fat: 15.49g | Carbs: 0.00g | Protein: 25.06g",
"food_id":"1695",
"food_name":"Chicken Thigh",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-thigh-ns-as-to-skin-eaten"
},
{
"food_description":"Per 101g - Calories: 239kcal | Fat: 13.60g | Carbs: 0.00g | Protein: 27.30g",
"food_id":"419178",
"food_name":"Rotisserie Chicken",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-rotisserie-ns-as-to-skin-eaten"
},
{
"brand_name":"Valbest",
"food_description":"Per 4 oz - Calories: 130kcal | Fat: 3.00g | Carbs: 0.00g | Protein: 26.00g",
"food_id":"3946778",
"food_name":"Chicken Breast",
"food_type":"Brand",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/valbest\/chicken-breast"
},
{
"food_description":"Per 101g - Calories: 216kcal | Fat: 11.15g | Carbs: 0.00g | Protein: 27.03g",
"food_id":"1677",
"food_name":"Chicken Drumstick",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-drumstick-ns-as-to-skin-eaten"
},
{
"food_description":"Per 101g - Calories: 190kcal | Fat: 7.41g | Carbs: 0.00g | Protein: 28.93g",
"food_id":"1628",
"food_name":"Roasted Broiled or Baked Chicken (Skin Not Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-roasted-broiled-or-baked-skin-not-eaten"
},
{
"food_description":"Per 101g - Calories: 239kcal | Fat: 13.60g | Carbs: 0.00g | Protein: 27.30g",
"food_id":"1623",
"food_name":"Chicken",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-ns-as-to-skin-eaten"
},
{
"brand_name":"Cub Foods",
"food_description":"Per 1 small - Calories: 110kcal | Fat: 2.50g | Carbs: 0.00g | Protein: 21.00g",
"food_id":"26245",
"food_name":"Boneless Skinless Chicken Breast",
"food_type":"Brand",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/cub-foods\/boneless-skinless-chicken-breast"
},
{
"food_description":"Per 96g - Calories: 279kcal | Fat: 16.60g | Carbs: 9.59g | Protein: 21.45g",
"food_id":"1636",
"food_name":"Baked or Fried Coated Chicken with Skin (Skin\/Coating Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-coated-baked-or-fried-prepared-with-skin-skin-coating-eaten"
},
{
"food_description":"Per 101g - Calories: 209kcal | Fat: 10.88g | Carbs: 0.00g | Protein: 25.94g",
"food_id":"1697",
"food_name":"Chicken Thigh (Skin Not Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-thigh-skin-not-eaten"
},
{
"food_description":"Per 101g - Calories: 290kcal | Fat: 19.46g | Carbs: 0.00g | Protein: 26.86g",
"food_id":"1713",
"food_name":"Chicken Wing",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-wing-ns-as-to-skin-eaten"
},
{
"brand_name":"Pilgrim\u0027s Pride",
"food_description":"Per 1 serving - Calories: 90kcal | Fat: 0.00g | Carbs: 0.00g | Protein: 22.00g",
"food_id":"25945",
"food_name":"Chicken Breast Tenderloins",
"food_type":"Brand",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/pilgrims-pride\/chicken-breast-tenderloins"
},
{
"food_description":"Per 103g - Calories: 241kcal | Fat: 10.17g | Carbs: 9.97g | Protein: 25.73g",
"food_id":"1657",
"food_name":"Baked or Fried Coated Chicken Breast Skinless (Coating Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-breast-coated-baked-or-fried-prepared-skinless-coating-eaten"
},
{
"food_description":"Per 101g - Calories: 247kcal | Fat: 15.49g | Carbs: 0.00g | Protein: 25.06g",
"food_id":"1696",
"food_name":"Chicken Thigh (Skin Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-thigh-skin-eaten"
},
{
"food_description":"Per 101g - Calories: 165kcal | Fat: 3.57g | Carbs: 0.00g | Protein: 31.02g",
"food_id":"1643",
"food_name":"Chicken Breast (Skin Not Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-breast-skin-not-eaten"
},
{
"food_description":"Per 101g - Calories: 190kcal | Fat: 7.41g | Carbs: 0.00g | Protein: 28.93g",
"food_id":"448917",
"food_name":"Grilled Chicken (Skin Not Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-grilled-skin-not-eaten"
},
{
"food_description":"Per 101g - Calories: 232kcal | Fat: 13.46g | Carbs: 0.00g | Protein: 25.96g",
"food_id":"1660",
"food_name":"Chicken Leg (Skin Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-leg-(drumstick-and-thigh)-skin-eaten"
},
{
"food_description":"Per 104g - Calories: 221kcal | Fat: 9.52g | Carbs: 0.00g | Protein: 31.92g",
"food_id":"1637",
"food_name":"Baked or Fried Coated Chicken with Skin (Skin\/Coating Not Eaten)",
"food_type":"Generic",
"food_url":"http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-coated-baked-or-fried-prepared-with-skin-skin-coating-not-eaten"
}
],
"max_results":"20",
"page_number":"0",
"total_results":"4726"
}
}
However i am only getting back this:
{ "foods": { "food": [ {"food_description": "Per 101g - Calories: 197kcal | Fat: 7.79g | Carbs: 0.00g | Protein: 29.80g", "food_id": "1641", "food_name": "Chicken Breast", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-breast-ns-as-to-skin-eaten" }, {"food_description": "Per 100g - Calories: 110kcal | Fat: 1.24g | Carbs: 0.00g | Protein: 23.09g", "food_id": "4881229", "food_name": "Skinless Chicken Breast", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-breast-skinless" }, {"food_description": "Per 101g - Calories: 239kcal | Fat: 13.60g | Carbs: 0.00g | Protein: 27.30g", "food_id": "448901", "food_name": "Grilled Chicken", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-grilled-ns-as-to-skin-eaten" }, {"food_description": "Per 101g - Calories: 247kcal | Fat: 15.49g | Carbs: 0.00g | Protein: 25.06g", "food_id": "1695", "food_name": "Chicken Thigh", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-thigh-ns-as-to-skin-eaten" }, {"food_description": "Per 101g - Calories: 239kcal | Fat: 13.60g | Carbs: 0.00g | Protein: 27.30g", "food_id": "419178", "food_name": "Rotisserie Chicken", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-rotisserie-ns-as-to-skin-eaten" }, {"brand_name": "Valbest", "food_description": "Per 4 oz - Calories: 130kcal | Fat: 3.00g | Carbs: 0.00g | Protein: 26.00g", "food_id": "3946778", "food_name": "Chicken Breast", "food_type": "Brand", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/valbest\/chicken-breast" }, {"food_description": "Per 101g - Calories: 216kcal | Fat: 11.15g | Carbs: 0.00g | Protein: 27.03g", "food_id": "1677", "food_name": "Chicken Drumstick", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-drumstick-ns-as-to-skin-eaten" }, {"food_description": "Per 101g - Calories: 190kcal | Fat: 7.41g | Carbs: 0.00g | Protein: 28.93g", "food_id": "1628", "food_name": "Roasted Broiled or Baked Chicken (Skin Not Eaten)", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-roasted-broiled-or-baked-skin-not-eaten" }, {"food_description": "Per 101g - Calories: 239kcal | Fat: 13.60g | Carbs: 0.00g | Protein: 27.30g", "food_id": "1623", "food_name": "Chicken", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-ns-as-to-skin-eaten" }, {"brand_name": "Cub Foods", "food_description": "Per 1 small - Calories: 110kcal | Fat: 2.50g | Carbs: 0.00g | Protein: 21.00g", "food_id": "26245", "food_name": "Boneless Skinless Chicken Breast", "food_type": "Brand", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/cub-foods\/boneless-skinless-chicken-breast" }, {"food_description": "Per 96g - Calories: 279kcal | Fat: 16.60g | Carbs: 9.59g | Protein: 21.45g", "food_id": "1636", "food_name": "Baked or Fried Coated Chicken with Skin (Skin\/Coating Eaten)", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-coated-baked-or-fried-prepared-with-skin-skin-coating-eaten" }, {"food_description": "Per 101g - Calories: 209kcal | Fat: 10.88g | Carbs: 0.00g | Protein: 25.94g", "food_id": "1697", "food_name": "Chicken Thigh (Skin Not Eaten)", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-thigh-skin-not-eaten" }, {"food_description": "Per 101g - Calories: 290kcal | Fat: 19.46g | Carbs: 0.00g | Protein: 26.86g", "food_id": "1713", "food_name": "Chicken Wing", "food_type": "Generic", "food_url": "http:\/\/www.fatsecret.com\/calories-nutrition\/generic\/chicken-wing-ns-as-to-skin-eaten" }, {"brand_name": "Pilgrim\u0027s Pride", "food_description": "Per 1 serving - Calories: 90kcal | Fat: 0.00g | Carbs: 0.00g | Protein: 22.00g", "foo
Found a good workaround in this post thanks to the comment above pointing out that Logcat has a maximum file size for single log entries. Instead of Log.d("tag", "msg"), use this function which will break it up into smaller strings for Logcat:
public static void largeLog(String tag, String content) {
if (content.length() > 4000) {
Log.d(tag, content.substring(0, 4000));
largeLog(tag, content.substring(4000));
} else {
Log.d(tag, content);
}
}
Related
I have an update query:
#Modifying
#Transactional
#Query("UPDATE Admin SET firstname = :firstname, lastname = :lastname, login = :login, superAdmin = :superAdmin, preferenceAdmin = :preferenceAdmin, address = :address, zipCode = :zipCode, city = :city, country = :country, email = :email, profile = :profile, postLoginUrl = :postLoginUrl WHERE id = :id")
public void update(#Param("firstname") String firstname, #Param("lastname") String lastname, #Param("login") String login, #Param("superAdmin") boolean superAdmin, #Param("preferenceAdmin") boolean preferenceAdmin, #Param("address") String address, #Param("zipCode") String zipCode, #Param("city") String city, #Param("country") String country, #Param("email") String email, #Param("profile") String profile, #Param("postLoginUrl") String postLoginUrl, #Param("id") Long id);
I'm trying to use it in an integration test:
adminRepository.update("Toto", "LeHeros", admin0.getLogin(), admin0.getSuperAdmin(), admin0.getPreferenceAdmin(), admin0.getAddress(), admin0.getZipCode(), admin0.getCity(), admin0.getCountry(), admin0.getEmail(), admin0.getProfile(), admin0.getPostLoginUrl(), admin0.getId());
Admin loadedAdmin = adminRepository.findOne(admin0.getId());
assertEquals("Toto", loadedAdmin.getFirstname());
assertEquals("LeHeros", loadedAdmin.getLastname());
But the fields are not updated and retain their initial values, the test thus failing.
I tried adding a flush right before the findOne query:
adminRepository.flush();
But the failed assertion remained identical.
I can see the update sql statement in the log:
update admin set firstname='Toto', lastname='LeHeros', login='stephane', super_admin=0, preference_admin=0,
address=NULL, zip_code=NULL, city=NULL, country=NULL, email='stephane#thalasoft.com', profile=NULL,
post_login_url=NULL where id=2839
But the log shows no sql that could relate to the finder:
Admin loadedAdmin = adminRepository.findOne(admin0.getId());
The finder sql statement is not making its way to the database.
Is it ignored for some caching reason ?
If I then add a call to the findByEmail and findByLogin finders as in:
adminRepository.update("Toto", "LeHeros", "qwerty", admin0.getSuperAdmin(), admin0.getPreferenceAdmin(), admin0.getAddress(), admin0.getZipCode(), admin0.getCity(), admin0.getCountry(), admin0.getEmail(), admin0.getProfile(), admin0.getPostLoginUrl(), admin0.getId());
Admin loadedAdmin = adminRepository.findOne(admin0.getId());
Admin myadmin = adminRepository.findByEmail(admin0.getEmail());
Admin anadmin = adminRepository.findByLogin("qwerty");
assertEquals("Toto", anadmin.getFirstname());
assertEquals("Toto", myadmin.getFirstname());
assertEquals("Toto", loadedAdmin.getFirstname());
assertEquals("LeHeros", loadedAdmin.getLastname());
then I can see in the log the sql statement being generated:
But the assertion:
assertEquals("Toto", myadmin.getFirstname());
still fails even though the trace shows the same domain object was retrieved:
TRACE [BasicExtractor] found [1037] as column [id14_]
One other thing that puzzles me with this other finder is that it shows a limit 2 clause even though it is supposed to return only one Admin object.
I thought there would always be a limit 1 when returning one domain object. Is this a wrong assumption on Spring Data ?
When pasting in a MySQL client, the sql statements displayed in the console log, the logic works fine:
mysql> insert into admin (version, address, city, country, email, firstname, lastname, login, password,
-> password_salt, post_login_url, preference_admin, profile, super_admin, zip_code) values (0,
-> NULL, NULL, NULL, 'zemail#thalasoft.com039', 'zfirstname039', 'zlastname039', 'zlogin039',
-> 'zpassword039', '', NULL, 0, NULL, 1, NULL);
Query OK, 1 row affected (0.07 sec)
mysql> select * from admin;
+------+---------+---------------+--------------+-----------+--------------+---------------+-------------+------------------+---------+----------+------+---------+-------------------------+---------+----------------+
| id | version | firstname | lastname | login | password | password_salt | super_admin | preference_admin | address | zip_code | city | country | email | profile | post_login_url |
+------+---------+---------------+--------------+-----------+--------------+---------------+-------------+------------------+---------+----------+------+---------+-------------------------+---------+----------------+
| 1807 | 0 | zfirstname039 | zlastname039 | zlogin039 | zpassword039 | | 1 | 0 | NULL | NULL | NULL | NULL | zemail#thalasoft.com039 | NULL | NULL |
+------+---------+---------------+--------------+-----------+--------------+---------------+-------------+------------------+---------+----------+------+---------+-------------------------+---------+----------------+
1 row in set (0.00 sec)
mysql> update admin set firstname='Toto', lastname='LeHeros', login='qwerty', super_admin=0, preference_admin=0, address=NULL, zip_code=NULL, city=NULL, country=NULL, email='stephane#thalasoft.com', profile=NULL, post_login_url=NULL where id=1807;
Query OK, 1 row affected (0.07 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from admin; +------+---------+-----------+----------+--------+--------------+---------------+-------------+------------------+---------+----------+------+---------+------------------------+---------+----------------+
| id | version | firstname | lastname | login | password | password_salt | super_admin | preference_admin | address | zip_code | city | country | email | profile | post_login_url |
+------+---------+-----------+----------+--------+--------------+---------------+-------------+------------------+---------+----------+------+---------+------------------------+---------+----------------+
| 1807 | 0 | Toto | LeHeros | qwerty | zpassword039 | | 0 | 0 | NULL | NULL | NULL | NULL | stephane#thalasoft.com | NULL | NULL |
+------+---------+-----------+----------+--------+--------------+---------------+-------------+------------------+---------+----------+------+---------+------------------------+---------+----------------+
1 row in set (0.00 sec)
mysql> select admin0_.id as id14_, admin0_.version as version14_, admin0_.address as address14_, admin0_.city as city14_, admin0_.country as country14_, admin0_.email as email14_, admin0_.firstname as firstname14_, admin0_.lastname as lastname14_, admin0_.login as login14_, admin0_.password as password14_, admin0_.password_salt as password11_14_, admin0_.post_login_url as post12_14_, admin0_.preference_admin as preference13_14_, admin0_.profile as profile14_, admin0_.super_admin as super15_14_, admin0_.zip_code as zip16_14_ from admin admin0_ where admin0_.email='stephane#thalasoft.com' limit 2;
+-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+
| id14_ | version14_ | address14_ | city14_ | country14_ | email14_ | firstname14_ | lastname14_ | login14_ | password14_ | password11_14_ | post12_14_ | preference13_14_ | profile14_ | super15_14_ | zip16_14_ |
+-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+
| 1807 | 0 | NULL | NULL | NULL | stephane#thalasoft.com | Toto | LeHeros | qwerty | zpassword039 | | NULL | 0 | NULL | 0 | NULL |
+-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+
1 row in set (0.00 sec)
mysql> select admin0_.id as id14_, admin0_.version as version14_, admin0_.address as address14_, admin0_.city as city14_, admin0_.country as country14_, admin0_.email as email14_, admin0_.firstname as firstname14_, admin0_.lastname as lastname14_, admin0_.login as login14_, admin0_.password as password14_, admin0_.password_salt as password11_14_, admin0_.post_login_url as post12_14_, admin0_.preference_admin as preference13_14_, admin0_.profile as profile14_, admin0_.super_admin as super15_14_, admin0_.zip_code as zip16_14_ from admin admin0_ where admin0_.login='qwerty' limit 2;
+-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+
| id14_ | version14_ | address14_ | city14_ | country14_ | email14_ | firstname14_ | lastname14_ | login14_ | password14_ | password11_14_ | post12_14_ | preference13_14_ | profile14_ | super15_14_ | zip16_14_ |
+-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+
| 1807 | 0 | NULL | NULL | NULL | stephane#thalasoft.com | Toto | LeHeros | qwerty | zpassword039 | | NULL | 0 | NULL | 0 | NULL |
+-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+
1 row in set (0.00 sec)
So why is this not reflected at the Java level ?
The EntityManager doesn't flush change automatically by default. You should use the following option with your statement of query:
#Modifying(clearAutomatically = true)
#Query("update RssFeedEntry feedEntry set feedEntry.read =:isRead where feedEntry.id =:entryId")
void markEntryAsRead(#Param("entryId") Long rssFeedEntryId, #Param("isRead") boolean isRead);
I finally understood what was going on.
When creating an integration test on a statement saving an object, it is recommended to flush the entity manager so as to avoid any false negative, that is, to avoid a test running fine but whose operation would fail when run in production. Indeed, the test may run fine simply because the first level cache is not flushed and no writing hits the database. To avoid this false negative integration test use an explicit flush in the test body. Note that the production code should never need to use any explicit flush as it is the role of the ORM to decide when to flush.
When creating an integration test on an update statement, it may be necessary to clear the entity manager so as to reload the first level cache. Indeed, an update statement completely bypasses the first level cache and writes directly to the database. The first level cache is then out of sync and reflects the old value of the updated object. To avoid this stale state of the object, use an explicit clear in the test body. Note that the production code should never need to use any explicit clear as it is the role of the ORM to decide when to clear.
My test now works just fine.
I was able to get this to work. I will describe my application and the integration test here.
The Example Application
The example application has two classes and one interface that are relevant to this problem:
The application context configuration class
The entity class
The repository interface
These classes and the repository interface are described in the following.
The source code of the PersistenceContext class looks as follows:
import com.jolbox.bonecp.BoneCPDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "net.petrikainulainen.spring.datajpa.todo.repository")
#PropertySource("classpath:application.properties")
public class PersistenceContext {
protected static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
protected static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
protected static final String PROPERTY_NAME_DATABASE_URL = "db.url";
protected static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_PACKAGES_TO_SCAN = "net.petrikainulainen.spring.datajpa.todo.model";
#Autowired
private Environment environment;
#Bean
public DataSource dataSource() {
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setJdbcUrl(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan(PROPERTY_PACKAGES_TO_SCAN);
Properties jpaProperties = new Properties();
jpaProperties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
jpaProperties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
jpaProperties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO));
jpaProperties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
jpaProperties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
entityManagerFactoryBean.setJpaProperties(jpaProperties);
return entityManagerFactoryBean;
}
}
Let's assume that we have a simple entity called Todo which source code looks as follows:
#Entity
#Table(name="todos")
public class Todo {
public static final int MAX_LENGTH_DESCRIPTION = 500;
public static final int MAX_LENGTH_TITLE = 100;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "description", nullable = true, length = MAX_LENGTH_DESCRIPTION)
private String description;
#Column(name = "title", nullable = false, length = MAX_LENGTH_TITLE)
private String title;
#Version
private long version;
}
Our repository interface has a single method called updateTitle() which updates the title of a todo entry. The source code of the TodoRepository interface looks as follows:
import net.petrikainulainen.spring.datajpa.todo.model.Todo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface TodoRepository extends JpaRepository<Todo, Long> {
#Modifying
#Query("Update Todo t SET t.title=:title WHERE t.id=:id")
public void updateTitle(#Param("id") Long id, #Param("title") String title);
}
The updateTitle() method is not annotated with the #Transactional annotation because I think that it is best to use a service layer as a transaction boundary.
The Integration Test
The Integration Test uses DbUnit, Spring Test and Spring-Test-DBUnit. It has three components which are relevant to this problem:
The DbUnit dataset which is used to initialize the database into a known state before the test is executed.
The DbUnit dataset which is used to verify that the title of the entity is updated.
The integration test.
These components are described with more details in the following.
The name of the DbUnit dataset file which is used to initialize the database to known state is toDoData.xml and its content looks as follows:
<dataset>
<todos id="1" description="Lorem ipsum" title="Foo" version="0"/>
<todos id="2" description="Lorem ipsum" title="Bar" version="0"/>
</dataset>
The name of the DbUnit dataset which is used to verify that the title of the todo entry is updated is called toDoData-update.xml and its content looks as follows (for some reason the version of the todo entry was not updated but the title was. Any ideas why?):
<dataset>
<todos id="1" description="Lorem ipsum" title="FooBar" version="0"/>
<todos id="2" description="Lorem ipsum" title="Bar" version="0"/>
</dataset>
The source code of the actual integration test looks as follows (Remember to annotate the test method with the #Transactional annotation):
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {PersistenceContext.class})
#TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class })
#DatabaseSetup("todoData.xml")
public class ITTodoRepositoryTest {
#Autowired
private TodoRepository repository;
#Test
#Transactional
#ExpectedDatabase("toDoData-update.xml")
public void updateTitle_ShouldUpdateTitle() {
repository.updateTitle(1L, "FooBar");
}
}
After I run the integration test, the test passes and the title of the todo entry is updated. The only problem which I am having is that the version field is not updated. Any ideas why?
I undestand that this description is a bit vague. If you want to get more information about writing integration tests for Spring Data JPA repositories, you can read my blog post about it.
The underlying problem here is the 1st level cache of JPA.
From the JPA spec Version 2.2 section 3.1. emphasise is mine:
An EntityManager instance is associated with a persistence context. A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance.
This is important because JPA tracks changes to that entity in order to flush them to the database.
As a side effect it also means within a single persistence context an entity gets only loaded once.
This why reloading the changed entity doesn't have any effect.
You have a couple of options how to handle this:
Evict the entity from the EntityManager.
This may be done by calling EntityManager.detach, annotating the updating method with #Modifying(clearAutomatically = true) which evicts all entities.
Make sure changes to these entities get flushed first or you might end up loosing changes.
Use EntityManager.refresh().
Use a different persistence context to load the entity.
The easiest way to do this is to do it in a separate transaction.
With Spring this can be done by having separate methods annotated with #Transactional on beans called from a bean not annotated with #Transactional.
Another way is to use a TransactionTemplate which works especially nicely in tests where it makes transaction boundaries very visible.
I struggled with the same problem where I was trying to execute an update query like the same as you did-
#Modifying
#Transactional
#Query(value = "UPDATE SAMPLE_TABLE st SET st.status=:flag WHERE se.referenceNo in :ids")
public int updateStatus(#Param("flag")String flag, #Param("ids")List<String> references);
This will work if you have put #EnableTransactionManagement annotation on the main class.
Spring 3.1 introduces the #EnableTransactionManagement annotation to be used in on #Configuration classes and enable transactional support.
I have a syntax error message for my JQL query whne my repository beans are trying to be initialized:
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: order near line 1, column 17 [select distinct order from com.github.eljah.mental.domain.Order order left join fetch order.shipments left join fetch order.subscriptions]
caused by this part in Spring data repo:
#Query("select distinct order from Order order left join fetch order.shipments left join fetch order.subscriptions")
the full output is attached below.
Spring data repository class:
#Repository
public interface OrderRepository extends JpaRepository<Order, Long>, JpaSpecificationExecutor<Order> {
#Query("select order from Order order where order.user.login = ?#{principal.username}")
List<Order> findByUserIsCurrentUser();
#Query(value = "select distinct order from Order order left join fetch order.shipments left join fetch order.subscriptions",
countQuery = "select count(distinct order) from Order order")
Page<Order> findAllWithEagerRelationships(Pageable pageable);
#Query("select distinct order from Order order left join fetch order.shipments left join fetch order.subscriptions")
List<Order> findAllWithEagerRelationships();
#Query("select order from Order order left join fetch order.shipments left join fetch order.subscriptions where order.id =:id")
Optional<Order> findOneWithEagerRelationships(#Param("id") Long id);
}
and the entity itself is:
#Entity
#Table(name = "jhi_order")
#org.springframework.data.elasticsearch.annotations.Document(indexName = "shipment", shards = 1, replicas = 0, refreshInterval = "-1")
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
#org.springframework.data.elasticsearch.annotations.Field(type = FieldType.Keyword)
private Long id;
#Column(name = "created")
private ZonedDateTime created;
#Column(name = "paid")
private ZonedDateTime paid;
#Column(name = "processed")
private Boolean processed;
#Column(name = "md_order")
private String mdOrder;
#Column(name = "operation")
private String operation;
#ManyToOne(optional = false)
#NotNull
#JsonIgnoreProperties("orders")
private User user;
#ManyToMany
#JoinTable(name = "jhi_order_shipments",
joinColumns = #JoinColumn(name = "order_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "shipments_id", referencedColumnName = "id"))
private Set<Shipment> shipments = new HashSet<>();
#ManyToMany
#JoinTable(name = "jhi_order_subscriptions",
joinColumns = #JoinColumn(name = "order_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "subscriptions_id", referencedColumnName = "id"))
private Set<AccessSubscription> subscriptions = new HashSet<>();
setters/getters are ommited. So, what is wrong there? I have similar SpringData repositories for the similar entities with the similar JQL queries and everything is ok. Or may be "order" is a kind of keywork in JQL?
| 2019-09-25 18:00:01.145 ERROR 8 --- [ main] o.h.hql.internal.ast.ErrorTracker : line 1:119: unexpected token: order
mental-app_1 |
mental-app_1 | antlr.NoViableAltException: unexpected token: order
mental-app_1 | at org.hibernate.hql.internal.antlr.HqlBaseParser.joinPath(HqlBaseParser.java:1760)
mental-app_1 | at org.hibernate.hql.internal.antlr.HqlBaseParser.fromJoin(HqlBaseParser.java:1640)
mental-app_1 | at org.hibernate.hql.internal.antlr.HqlBaseParser.fromClause(HqlBaseParser.java:1355)
mental-app_1 | at org.hibernate.hql.internal.antlr.HqlBaseParser.selectFrom(HqlBaseParser.java:1063)
mental-app_1 | at org.hibernate.hql.internal.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:748)
mental-app_1 | at org.hibernate.hql.internal.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:319)
mental-app_1 | at org.hibernate.hql.internal.antlr.HqlBaseParser.statement(HqlBaseParser.java:198)
mental-app_1 | at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:289)
mental-app_1 | at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:188)
mental-app_1 | at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:143)
mental-app_1 | at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:119)
mental-app_1 | at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
mental-app_1 | at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
mental-app_1 | at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:611)
mental-app_1 | at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:720)
mental-app_1 | at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:104)
mental-app_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
mental-app_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
mental-app_1 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
mental-app_1 | at java.base/java.lang.reflect.Method.invoke(Unknown Source)
mental-app_1 | at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)
mental-app_1 | at com.sun.proxy.$Proxy173.createQuery(Unknown Source)
mental-app_1 | at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87)
mental-app_1 | at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:63)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:76)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:56)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:142)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:209)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:79)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lookupQuery(RepositoryFactorySupport.java:566)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(RepositoryFactorySupport.java:559)
mental-app_1 | at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
mental-app_1 | at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
mental-app_1 | at java.base/java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Unknown Source)
mental-app_1 | at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
mental-app_1 | at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
mental-app_1 | at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
mental-app_1 | at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
mental-app_1 | at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
mental-app_1 | at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.mapMethodsToQuery(RepositoryFactorySupport.java:561)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$new$0(RepositoryFactorySupport.java:551)
mental-app_1 | at java.base/java.util.Optional.map(Unknown Source)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:551)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:324)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297)
mental-app_1 | at org.springframework.data.util.Lazy.getNullable(Lazy.java:211)
mental-app_1 | at org.springframework.data.util.Lazy.get(Lazy.java:94)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300)
mental-app_1 | at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:121)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
mental-app_1 | at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
mental-app_1 | at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277)
mental-app_1 | at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1251)
mental-app_1 | at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1171)
mental-app_1 | at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857)
mental-app_1 | at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760)
mental-app_1 | at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1341)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1187)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
mental-app_1 | at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
mental-app_1 | at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845)
mental-app_1 | at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
mental-app_1 | at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
mental-app_1 | at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
mental-app_1 | at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
mental-app_1 | at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
mental-app_1 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
mental-app_1 | at com.github.eljah.mental.MentalApp.main(MentalApp.java:63)
mental-app_1 |
mental-app_1 | 2019-09-25 18:00:01.153 WARN 8 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderQueryService' defined in file [/app/classes/com/github/eljah/mental/service/OrderQueryService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.github.eljah.mental.repository.OrderRepository.findAllWithEagerRelationships()!
mental-app_1 | 2019-09-25 18:00:01.361 ERROR 8 --- [ main] o.s.boot.SpringApplication : Application run failed
mental-app_1 |
mental-app_1 | org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderQueryService' defined in file [/app/classes/com/github/eljah/mental/service/OrderQueryService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.github.eljah.mental.repository.OrderRepository.findAllWithEagerRelationships()!
mental-app_1 | at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769)
mental-app_1 | at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1341)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1187)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
mental-app_1 | at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
mental-app_1 | at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845)
mental-app_1 | at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
mental-app_1 | at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
mental-app_1 | at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
mental-app_1 | at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
mental-app_1 | at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
mental-app_1 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
mental-app_1 | at com.github.eljah.mental.MentalApp.main(MentalApp.java:63)
mental-app_1 | Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.github.eljah.mental.repository.OrderRepository.findAllWithEagerRelationships()!
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
mental-app_1 | at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
mental-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
mental-app_1 | at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277)
mental-app_1 | at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1251)
mental-app_1 | at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1171)
mental-app_1 | at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857)
mental-app_1 | at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760)
mental-app_1 | ... 17 common frames omitted
mental-app_1 | Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.github.eljah.mental.repository.OrderRepository.findAllWithEagerRelationships()!
mental-app_1 | at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:93)
mental-app_1 | at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:63)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:76)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:56)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:142)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:209)
mental-app_1 | at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:79)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lookupQuery(RepositoryFactorySupport.java:566)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(RepositoryFactorySupport.java:559)
mental-app_1 | at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
mental-app_1 | at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
mental-app_1 | at java.base/java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Unknown Source)
mental-app_1 | at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
mental-app_1 | at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
mental-app_1 | at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
mental-app_1 | at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
mental-app_1 | at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
mental-app_1 | at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.mapMethodsToQuery(RepositoryFactorySupport.java:561)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$new$0(RepositoryFactorySupport.java:551)
mental-app_1 | at java.base/java.util.Optional.map(Unknown Source)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:551)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:324)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297)
mental-app_1 | at org.springframework.data.util.Lazy.getNullable(Lazy.java:211)
mental-app_1 | at org.springframework.data.util.Lazy.get(Lazy.java:94)
mental-app_1 | at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300)
mental-app_1 | at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:121)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
mental-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
mental-app_1 | ... 28 common frames omitted
mental-app_1 | Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: order near line 1, column 17 [select distinct order from com.github.eljah.mental.domain.Order order left join fetch order.shipments left join fetch order.subscriptions]
mental-app_1 | at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
mental-app_1 | at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
mental-app_1 | at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
mental-app_1 | at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:729)
mental-app_1 | at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:104)
mental-app_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
mental-app_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
mental-app_1 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
mental-app_1 | at java.base/java.lang.reflect.Method.invoke(Unknown Source)
mental-app_1 | at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)
mental-app_1 | at com.sun.proxy.$Proxy173.createQuery(Unknown Source)
mental-app_1 | at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87)
mental-app_1 | ... 57 common frames omitted
mental-app_1 | Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: order near line 1, column 17 [select distinct order from com.github.eljah.mental.domain.Order order left join fetch order.shipments left join fetch order.subscriptions]
mental-app_1 | at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
mental-app_1 | at org.hibernate.hql.internal.ast.ErrorTracker.throwQueryException(ErrorTracker.java:93)
mental-app_1 | at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:296)
mental-app_1 | at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:188)
mental-app_1 | at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:143)
mental-app_1 | at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:119)
mental-app_1 | at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
mental-app_1 | at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
mental-app_1 | at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:611)
mental-app_1 | at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:720)
mental-app_1 | ... 65 common frames omitted
The word order (which you seem to be trying to use as a variable name in your query) is a JPQL reserved word. Use o instead, and I strongly recommend that you consider externalizing the "current user" so that you pass in a user or user ID as a parameter and resolve it elsewhere; doing that inside the #Query introduces a hard coupling that's also difficult to test.
Error from jboss startup when deploying an ear file:
sob_backend | ... 40 more
sob_backend |
sob_backend | 09:44:46,667 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/sob-handler-web]] (ServerService Thread Pool -- 98) JBWEB000287: Exception sending context initialized event to listener instance of class org.apache.shiro.web.env.EnvironmentLoaderListener: org.apache.shiro.config.ConfigurationException: Unable to set property 'sessionManager.sessionDAO' with value [se.cehis.efsob.web.authorization.shiro.CustomShiroSessionDAO#cc7e7ac] on object of type org.apache.shiro.web.mgt.DefaultWebSecurityManager. If 'se.cehis.efsob.web.authorization.shiro.CustomShiroSessionDAO#cc7e7ac' is a reference to another (previously defined) object, prefix it with '$' to indicate that the referenced object should be used as the actual value. For example, $se.cehis.efsob.web.authorization.shiro.CustomShiroSessionDAO#cc7e7ac
sob_backend | at org.apache.shiro.config.ReflectionBuilder.setProperty(ReflectionBuilder.java:659) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.ReflectionBuilder.applyProperty(ReflectionBuilder.java:608) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.ReflectionBuilder.applyProperty(ReflectionBuilder.java:720) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.ReflectionBuilder.applySingleProperty(ReflectionBuilder.java:364) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.ReflectionBuilder.applyProperty(ReflectionBuilder.java:325) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.ReflectionBuilder$AssignmentStatement.doExecute(ReflectionBuilder.java:955) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.ReflectionBuilder$Statement.execute(ReflectionBuilder.java:887) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.ReflectionBuilder$BeanConfigurationProcessor.execute(ReflectionBuilder.java:765) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:260) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.IniSecurityManagerFactory.buildInstances(IniSecurityManagerFactory.java:167) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:130) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:108) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:94) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:46) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.config.IniFactorySupport.createInstance(IniFactorySupport.java:123) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.util.AbstractFactory.getInstance(AbstractFactory.java:47) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.web.env.IniWebEnvironment.createWebSecurityManager(IniWebEnvironment.java:203) [shiro-web-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.web.env.IniWebEnvironment.configure(IniWebEnvironment.java:99) [shiro-web-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.web.env.IniWebEnvironment.init(IniWebEnvironment.java:92) [shiro-web-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:45) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:40) [shiro-core-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.web.env.EnvironmentLoader.createEnvironment(EnvironmentLoader.java:221) [shiro-web-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.web.env.EnvironmentLoader.initEnvironment(EnvironmentLoader.java:133) [shiro-web-1.3.2.jar:1.3.2]
sob_backend | at org.apache.shiro.web.env.EnvironmentLoaderListener.contextInitialized(EnvironmentLoaderListener.java:58) [shiro-web-1.3.2.jar:1.3.2]
sob_backend | at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3339) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
sob_backend | at org.apache.catalina.core.StandardContext.start(StandardContext.java:3780) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
sob_backend | at org.jboss.as.web.deployment.WebDeploymentService.doStart(WebDeploymentService.java:163) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
sob_backend | at org.jboss.as.web.deployment.WebDeploymentService.access$000(WebDeploymentService.java:61) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
sob_backend | at org.jboss.as.web.deployment.WebDeploymentService$1.run(WebDeploymentService.java:96) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
sob_backend | at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_181]
sob_backend | at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_181]
sob_backend | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_181]
sob_backend | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_181]
sob_backend | at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_181]
sob_backend | at org.jboss.threads.JBossThread.run(JBossThread.java:122)
sob_backend | Caused by: java.lang.IllegalArgumentException: Cannot invoke org.apache.shiro.session.mgt.DefaultSessionManager.setSessionDAO on bean class 'class org.apache.shiro.web.session.mgt.DefaultWebSessionManager' - argument type mismatch - had objects of type "se.cehis.efsob.web.authorization.shiro.CustomShiroSessionDAO" but expected signature "org.apache.shiro.session.mgt.eis.SessionDAO"
sob_backend | at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2235) [commons-beanutils-1.8.3.jar:1.8.3]
sob_backend | at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2151) [commons-beanutils-1.8.3.jar:1.8.3]
sob_backend | at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1957) [commons-beanutils-1.8.3.jar:1.8.3]
sob_backend | at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:2064) [commons-beanutils-1.8.3.jar:1.8.3]
sob_backend | at org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:1017) [commons-beanutils-1.8.3.jar:1.8.3]
sob_backend | at org.apache.commons.beanutils.BeanUtils.setProperty(BeanUtils.java:456) [commons-beanutils-1.8.3.jar:1.8.3]
sob_backend | at org.apache.shiro.config.ReflectionBuilder.setProperty(ReflectionBuilder.java:651) [shiro-core-1.3.2.jar:1.3.2]
Relevant line:
Cannot invoke org.apache.shiro.session.mgt.DefaultSessionManager.setSessionDAO on bean class 'class org.apache.shiro.web.session.mgt.DefaultWebSessionManager' - argument type mismatch - had objects of type "se.cehis.efsob.web.authorization.shiro.CustomShiroSessionDAO" but expected signature "org.apache.shiro.session.mgt.eis.SessionDAO"
shiro.ini configuration file:
[main]
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
;cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
cacheManager = se.cehis.sob.cache.EfsobCacheManager
sessionDAO = se.cehis.efsob.web.authorization.shiro.CustomShiroSessionDAO
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.sessionIdCookie.name = e_session_id
securityManager.sessionManager.sessionIdCookie.path = /
;securityManager.sessionManager.sessionIdCookie.secure = true
securityManager.cacheManager = $cacheManager
securityManager.sessionManager.sessionDAO = $sessionDAO
;jdbcRealm=se.cehis.efsob.common.security.JdbcRealmImpl
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.authenticationQuery = SELECT ID FROM ACL_USER WHERE ID = ?
jdbcRealm.userRolesQuery = SELECT ROLE_NAME FROM ACL_ROLES where USER_ID = ?
jdbcRealm.permissionsQuery = SELECT PERMISSION_NAME FROM ACL_PERMISSION WHERE ROLE_NAME = ?
jdbcRealm.permissionsLookupEnabled = true
ds = org.apache.shiro.jndi.JndiObjectFactory
ds.resourceName = java:jboss/datasources/efobDS
jdbcRealm.dataSource= $ds
I've tried to upgrade the shiro maven version to 1.4.0 but I believe the same error still occurring.
Anyone that can shed some light on this?
I'm working on project which is recently upgraded to 3.7.1, after upgrade whenever I'm using more than 1 request ( in my case it's 3 requests ) at same time I'm getting this error.
IllegalStateException: UT000021: Session already invalidated"
the exception in log is this:
gateway-app_1 | at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
gateway-app_1 | at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
gateway-app_1 | at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
gateway-app_1 | at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
gateway-app_1 | at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
gateway-app_1 | at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119)
gateway-app_1 | at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:285)
gateway-app_1 | at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:264)
gateway-app_1 | at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
gateway-app_1 | at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:175)
gateway-app_1 | at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
gateway-app_1 | at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:802)
gateway-app_1 | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
gateway-app_1 | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
gateway-app_1 | at java.lang.Thread.run(Thread.java:745)
gateway-app_1 | Caused by: java.lang.IllegalStateException: UT000021: Session already invalidated
gateway-app_1 | at io.undertow.server.session.InMemorySessionManager$SessionImpl.invalidate(InMemorySessionManager.java:521)
gateway-app_1 | at io.undertow.server.session.InMemorySessionManager$SessionImpl.invalidate(InMemorySessionManager.java:507)
gateway-app_1 | at io.undertow.servlet.spec.HttpSessionImpl.invalidate(HttpSessionImpl.java:198)
gateway-app_1 | at com.hazelcast.web.WebFilter$RequestWrapper.readSessionFromLocal(WebFilter.java:507)
gateway-app_1 | at com.hazelcast.web.WebFilter$RequestWrapper.getSession(WebFilter.java:471)
gateway-app_1 | at com.hazelcast.web.WebFilter$RequestWrapper.getSession(WebFilter.java:410)
gateway-app_1 | at org.springframework.web.servlet.support.SessionFlashMapManager.retrieveFlashMaps(SessionFlashMapManager.java:45)
gateway-app_1 | at org.springframework.web.servlet.support.AbstractFlashMapManager.retrieveAndUpdate(AbstractFlashMapManager.java:93)
gateway-app_1 | at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:889)
gateway-app_1 | at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
gateway-app_1 | ... 96 common frames omitted
Is there any solution?
UPDATE 01:
this is my gateway .yo-rc.json
{
"generator-jhipster": {
"jhipsterVersion": "3.7.1",
"baseName": "gateway",
"packageName": "com.my.package.gateway",
"packageFolder": "com/my/package/gateway",
"serverPort": "8080",
"authenticationType": "jwt",
"hibernateCache": "no",
"clusteredHttpSession": "hazelcast",
"websocket": false,
"databaseType": "mongodb",
"devDatabaseType": "mongodb",
"prodDatabaseType": "mongodb",
"searchEngine": false,
"buildTool": "gradle",
"jwtSecretKey": "fdsfsdfsfsfs",
"useSass": true,
"applicationType": "gateway",
"testFrameworks": [
"gatling",
"cucumber",
"protractor"
],
"jhiPrefix": "jhi",
"enableTranslation": true,
"nativeLanguage": "en",
"languages": [
"en"
]
}
}
I am using jmxtrans to collect JMX stats from a remote JVM machine and writing the output to Opentsdb using OpenTsdbWriter, but after starting the jmxtrans service i am able to see that its not able to write the results to Opentsdb.
I tried to find out the sollution over google but not getting the desired answer, could someone help me out to resolve it:-
Below is the stack trace of the exception from Logs:-
[06 Sep 2016 23:13:58] [jmxtrans-result-6] 21573814 WARN (com.googlecode.jmxtrans.jmx.ResultProcessor$1:60) - Could not write results [Result(attributeName=Usage, className=sun.management.MemoryPoolImpl, objDomain=java.lang, typeName=type=MemoryPool,name=Metaspace, values={init=0, committed=20185088, max=-1, used=19304024}, epoch=1473183838891, keyAlias=memorypool), Result(attributeName=Usage, className=sun.management.MemoryPoolImpl, objDomain=java.lang, typeName=type=MemoryPool,name=PS Old Gen, values={init=87031808, committed=87031808, max=1375731712, used=16885688}, epoch=1473183838901, keyAlias=memorypool), Result(attributeName=Usage, className=sun.management.MemoryPoolImpl, objDomain=java.lang, typeName=type=MemoryPool,name=PS Eden Space, values={init=32505856, committed=24117248, max=686817280, used=4032656}, epoch=1473183838903, keyAlias=memorypool), Result(attributeName=Usage, className=sun.management.MemoryPoolImpl, objDomain=java.lang, typeName=type=MemoryPool,name=Compressed Class Space, values={init=0, committed=2359296, max=1073741824, used=2134656}, epoch=1473183838904, keyAlias=memorypool), Result(attributeName=Usage, className=sun.management.MemoryPoolImpl, objDomain=java.lang, typeName=type=MemoryPool,name=Code Cache, values={init=2555904, committed=9633792, max=251658240, used=9103552}, epoch=1473183838905, keyAlias=memorypool), Result(attributeName=Usage, className=sun.management.MemoryPoolImpl, objDomain=java.lang, typeName=type=MemoryPool,name=PS Survivor Space, values={init=5242880, committed=524288, max=524288, used=327680}, epoch=1473183838906, keyAlias=memorypool)] of query Query(objectName=java.lang:type=MemoryPool,name=*, keys=[], attr=[Usage], typeNames=[], resultAlias=memorypool, useObjDomainAsKey=false, allowDottedKeys=false, useAllTypeNames=false, outputWriterInstances=[BaseOutputWriter(typeNames=[], debugEnabled=false, settings={host=10.143.1.43, port=4242}, valueTransformer=com.googlecode.jmxtrans.model.results.IdentityValueTransformer#35a68c72), BaseOutputWriter(typeNames=[], debugEnabled=false, settings={}, valueTransformer=com.googlecode.jmxtrans.model.results.IdentityValueTransformer#3b6164b6)]) to output writer BaseOutputWriter(typeNames=[], debugEnabled=false, settings={host=10.143.1.43, port=4242}, valueTransformer=com.googlecode.jmxtrans.model.results.IdentityValueTransformer#35a68c72)
java.lang.NullPointerException
at com.googlecode.jmxtrans.model.output.support.opentsdb.OpenTSDBMessageFormatter.processOneMetric(OpenTSDBMessageFormatter.java:196)
at com.googlecode.jmxtrans.model.output.support.opentsdb.OpenTSDBMessageFormatter.formatResult(OpenTSDBMessageFormatter.java:159)
at com.googlecode.jmxtrans.model.output.support.opentsdb.OpenTSDBMessageFormatter.access$000(OpenTSDBMessageFormatter.java:54)
at com.googlecode.jmxtrans.model.output.support.opentsdb.OpenTSDBMessageFormatter$1.apply(OpenTSDBMessageFormatter.java:170)
at com.googlecode.jmxtrans.model.output.support.opentsdb.OpenTSDBMessageFormatter$1.apply(OpenTSDBMessageFormatter.java:166)
at com.google.common.collect.Iterators$8.transform(Iterators.java:817)
at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48)
at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48)
at com.google.common.collect.Iterators$5.hasNext(Iterators.java:569)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:249)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:209)
at com.google.common.collect.FluentIterable.toList(FluentIterable.java:484)
at com.googlecode.jmxtrans.model.output.support.opentsdb.OpenTSDBMessageFormatter.formatResults(OpenTSDBMessageFormatter.java:173)
at com.googlecode.jmxtrans.model.output.OpenTSDBWriter.internalWrite(OpenTSDBWriter.java:116)
at com.googlecode.jmxtrans.model.output.BaseOutputWriter.doWrite(BaseOutputWriter.java:157)
at com.googlecode.jmxtrans.jmx.ResultProcessor$1.run(ResultProcessor.java:58)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=SystemLoadAverage, className=sun.management.OperatingSystemImpl, objDomain=java.lang, typeName=type=OperatingSystem, values={SystemLoadAverage=0.09}, epoch=1473183838891, keyAlias=null)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=AvailableProcessors, className=sun.management.OperatingSystemImpl, objDomain=java.lang, typeName=type=OperatingSystem, values={AvailableProcessors=4}, epoch=1473183838891, keyAlias=null)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=TotalPhysicalMemorySize, className=sun.management.OperatingSystemImpl, objDomain=java.lang, typeName=type=OperatingSystem, values={TotalPhysicalMemorySize=8252579840}, epoch=1473183838891, keyAlias=null)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=FreePhysicalMemorySize, className=sun.management.OperatingSystemImpl, objDomain=java.lang, typeName=type=OperatingSystem, values={FreePhysicalMemorySize=170389504}, epoch=1473183838891, keyAlias=null)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=TotalSwapSpaceSize, className=sun.management.OperatingSystemImpl, objDomain=java.lang, typeName=type=OperatingSystem, values={TotalSwapSpaceSize=1073737728}, epoch=1473183838891, keyAlias=null)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=FreeSwapSpaceSize, className=sun.management.OperatingSystemImpl, objDomain=java.lang, typeName=type=OperatingSystem, values={FreeSwapSpaceSize=1073737728}, epoch=1473183838891, keyAlias=null)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=OpenFileDescriptorCount, className=sun.management.OperatingSystemImpl, objDomain=java.lang, typeName=type=OperatingSystem, values={OpenFileDescriptorCount=83}, epoch=1473183838891, keyAlias=null)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=MaxFileDescriptorCount, className=sun.management.OperatingSystemImpl, objDomain=java.lang, typeName=type=OperatingSystem, values={MaxFileDescriptorCount=50000}, epoch=1473183838891, keyAlias=null)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=HeapMemoryUsage, className=sun.management.MemoryImpl, objDomain=java.lang, typeName=type=Memory, values={init=130023424, committed=111673344, max=1834483712, used=21039656}, epoch=1473183838891, keyAlias=heap)
INFO | jvm 1 | 2016/09/06 23:13:58 | Result(attributeName=NonHeapMemoryUsage, className=sun.management.MemoryImpl, objDomain=java.lang, typeName=type=Memory, values={init=2555904, committed=32178176, max=-1, used=30542232}, epoch=1473183838891, keyAlias=heap)
My Config.Json looks like the below:-
{
"servers": [
{
"numQueryThreads": "2",
"host": "xx.xx.xx.xx",
"port": "1099",
"queries": [
{
"outputWriters": [
{
"#class": "com.googlecode.jmxtrans.model.output.StdOutWriter"
},
{
"#class": "com.googlecode.jmxtrans.model.output.OpenTSDBWriter",
"settings": {
"host": "xx.xx.xx.xx",
"port": "4242"
}
}
],
"obj": "java.lang:type=OperatingSystem",
"attr": [
"SystemLoadAverage",
"AvailableProcessors",
"TotalPhysicalMemorySize",
"FreePhysicalMemorySize",
"TotalSwapSpaceSize",
"FreeSwapSpaceSize",
"OpenFileDescriptorCount",
"MaxFileDescriptorCount"
]
},
{
"outputWriters": [
{
"#class": "com.googlecode.jmxtrans.model.output.StdOutWriter"
},
{
"#class": "com.googlecode.jmxtrans.model.output.OpenTSDBWriter",
"settings": {
"host": "xx.xx.xx.xx",
"port": "4242"
}
}
],
"resultAlias": "heap",
"obj": "java.lang:type=Memory",
"attr": [
"HeapMemoryUsage",
"NonHeapMemoryUsage"
]
},
{
"outputWriters": [
{
"#class": "com.googlecode.jmxtrans.model.output.StdOutWriter"
},
{
"#class": "com.googlecode.jmxtrans.model.output.OpenTSDBWriter",
"settings": {
"host": "xx.xx.xx.xx",
"port": "4242"
}
}
],
"resultAlias": "cmsoldgen",
"obj": "java.lang:name=CMS Old Gen,type=MemoryPool",
"attr": [
"Usage"
]
},
{
"outputWriters": [
{
"#class": "com.googlecode.jmxtrans.model.output.StdOutWriter"
},
{
"#class": "com.googlecode.jmxtrans.model.output.OpenTSDBWriter",
"settings": {
"host": "xx.xx.xx.xx",
"port": "4242"
}
}
],
"resultAlias": "gc",
"obj": "java.lang:type=GarbageCollector,name=",
"attr": [
"CollectionCount",
"CollectionTime"
]
},
{
"outputWriters": [
{
"#class": "com.googlecode.jmxtrans.model.output.StdOutWriter",
"settings": {}
},
{
"#class": "com.googlecode.jmxtrans.model.output.OpenTSDBWriter",
"settings": {
"host": "xx.xx.xx.xx",
"port": "4242"
}
}
],
"resultAlias": "memorypool",
"obj": "java.lang:type=MemoryPool,name=",
"attr": [
"Usage"
]
},
{
"outputWriters": [
{
"#class": "com.googlecode.jmxtrans.model.output.StdOutWriter"
},
{
"#class": "com.googlecode.jmxtrans.model.output.OpenTSDBWriter",
"settings": {
"host": "xx.xx.xx.xx",
"port": "4242"
}
}
],
"resultAlias": "threads",
"obj": "java.lang:type=Threading",
"attr": [
"DaemonThreadCount",
"PeakThreadCount",
"ThreadCount",
"TotalStartedThreadCount"
]
},
{
"outputWriters": [
{
"#class": "com.googlecode.jmxtrans.model.output.StdOutWriter"
},
{
"#class": "com.googlecode.jmxtrans.model.output.OpenTSDBWriter",
"settings": {
"host": "xx.xx.xx.xx",
"port": "4242"
}
}
],
"resultAlias": "tomcat8-connectors",
"obj": "Catalina:type=ThreadPool,name=",
"attr": [
"currentThreadCount",
"currentThreadsBusy"
]
},
{
"outputWriters": [
{
"#class": "com.googlecode.jmxtrans.model.output.StdOutWriter"
},
{
"#class": "com.googlecode.jmxtrans.model.output.OpenTSDBWriter",
"settings": {
"host": "xx.xx.xx.xx",
"port": "4242"
}
}
],
"resultAlias": "tomcat8-requests",
"obj": "Catalina:type=GlobalRequestProcessor,name=",
"attr": [
"bytesReceived",
"bytesSent",
"errorCount",
"processingTime",
"requestCount"
]
}
]
}
]
}
This is a bug in jmxtrans (https://github.com/jmxtrans/jmxtrans/issues/487) triggered when the typeNames settings hasn't been set.
Add "typeNames": [] to your OpenTSDBWriter settings as a workaround. You'll need to add it to all of the relevant sections.