EDIT: The code has been updated to include the changes suggested by #Igor Artamonov,
the problem however still occurs! I did noticed the following though with reference to this image, owner 2 had a height value and no tool_proficiency value until owner 3 was added, then 2's height value disappeared and 2's tool value appeared, 2 had smith's tools when it was created End of Edit
This May be similar to "This Question" but I couldn't fix the problem using the solutions given there and I couldn't post a comment because I have too little rep :( so I hope you don't mind me asking the question I have here :) *note if there is a better place for me to put my question or any problems do tell me, I am very new here :P
I have a java helper for my webpage that sets the properties for an entity in the datastore but every time at least one item is missed if not more? all the items are set using the same function!
The code on the JSP page:
String Username = (String)session.getAttribute("username");
System.out.println("Username carried from session variable = "+Username);
if(request.getParameter("alignment")!=null
&& request.getParameter("Size")!=null
&& request.getParameter("age")!=null
&& request.getParameter("tools")!=null){
String HD = "Hill Dwarf";
String Age = request.getParameter("age");
String Alignment = request.getParameter("alignment");
int Size = Integer.parseInt(request.getParameter("Size"));
int Rem = Size%12;
Size = (Size-(Size%12))/12;
String Height = (Size+"ft "+Rem+"in");
String Tools = request.getParameter("tools");
System.out.println("setString for hill dwarf: ");
login.setString(Username, "Race", HD);
System.out.println("setString for age: ");
login.setString(Username, "Age", Age);
System.out.println("setString for Alignment: ");
login.setString(Username, "Alignment", Alignment);
System.out.println("setString for height: ");
login.setString(Username, "Height", Height);
System.out.println("setString for tools: ");
login.setString(Username, "Tool_Proficiency", Tools);
System.out.println("redirecting to class page");
response.sendRedirect("class.jsp");
}
The code in the login helper:
public void setString(String usernamein,String columnin, String stringin){
Transaction txn = datastore.beginTransaction();
try{
Filter usernamefilter = new FilterPredicate("owner",
FilterOperator.EQUAL, usernamein);
Query validuserquery = new Query("Char").setFilter(usernamefilter);
Entity theUser = datastore.prepare(validuserquery).asSingleEntity();
System.out.println("Username passed to setString = "+usernamein);
System.out.println("Column name passed to setString = "+columnin);
System.out.println("String passed to setString = "+stringin);
System.out.println("Query = "+validuserquery);
if (theUser==null && counter < 30){
System.out.println("theUser was equal to null");
try {
System.out.println("sleeping for 400ms");
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
counter ++;
System.out.println("counter increased, counter = "+counter);
System.out.println("Recursing function");
setString(usernamein,columnin,stringin);
}else{
System.out.println("theUser was not == null ");
System.out.println("inputting: "+columnin+" = "+stringin);
theUser.setProperty(columnin,stringin);
datastore.put(theUser);
System.out.println("item added");
}
txn.commit();
}finally{
if (txn.isActive()){
txn.rollback();
}
}
}
If anyone needs me to explain the code I will just ask :)
Okay so this is the code for putting Age, Alignement, etc... into the datastore but it gives this result in the datastore? I don't for the life of me know why!?
This would have been an image but I need 10 rep for that, so you'll have to follow this link for the image :( again sorry
This is what the eclipse console gets from all the System.out.println()'s
this is not code but i'll put it in a code snippet for readability :)
HillDwarf page loaded
Username carried from session variable = 12
setString for hill dwarf:
Username passed to setString = 12
Column name passed to setString = Race
String passed to setString = Hill Dwarf
Query = SELECT * FROM Char WHERE owner = 12
theUSer was not == null
inputting: Race = Hill Dwarf
item added
setString for age:
Username passed to setString = 12
Column name passed to setString = Age
String passed to setString = 10
Query = SELECT * FROM Char WHERE owner = 12
theUSer was not == null
inputting: Age = 10
item added
setString for Alignment:
Username passed to setString = 12
Column name passed to setString = Alignment
String passed to setString = N
Query = SELECT * FROM Char WHERE owner = 12
theUSer was not == null
inputting: Alignment = N
item added
setString for height:
Username passed to setString = 12
Column name passed to setString = Height
String passed to setString = 4ft 5in
Query = SELECT * FROM Char WHERE owner = 12
theUSer was not == null
inputting: Height = 4ft 5in
item added
setString for tools:
Username passed to setString = 12
Column name passed to setString = Tool_Proficiency
String passed to setString = Brewer's Supplies
Query = SELECT * FROM Char WHERE owner = 12
theUSer was not == null
inputting: Tool_Proficiency = Brewer's Supplies
item added
redirecting to class page
so My problem as seen in the image, is that the datastore is not getting all the items every time, even though I use the same helper method each time!
please help I have been trying to fix this for days with several approaches :(
You aren't using transaction, so some writes are replaced by others.
Try this:
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Transaction txn = datastore.beginTransaction();
try {
/// your current code
txn.commit();
} finally {
if (txn.isActive()) {
txn.rollback();
}
}
See https://cloud.google.com/appengine/docs/java/datastore/transactions
PS you also should understand that your current code is 4x times more expensive than code that does same update in one .put. I don't see any reason to make it 4 times, for every field separately.
I am answering my own question as I finally fixed the problem today :S Oh my was it a stupid one too!
In case any one in the future has this problem, make sure you are using keys correctly! When Char was created I used this:
Key Charkey = KeyFactory.createKey("owner","id");
Entity Char = new Entity("Char", Charkey);
In my helper I removed the Transaction (good idea unfortunately it didn't work for me), and -Replaced:
Filter usernamefilter = new FilterPredicate("owner", FilterOperator.EQUAL, usernamein);
Query validuserquery = new Query("Char").setFilter(usernamefilter);
-With:
Key Charkey = KeyFactory.createKey("owner","id");
Filter usernamefilter = new FilterPredicate("owner", FilterOperator.EQUAL, usernamein);
Query validuserquery = new Query("Char",Charkey).setFilter(usernamefilter);
pretty silly mistake that cost me hours! I am so new to datastore though so I kinda expect these mistakes anyway hopefully this fixes someone elses problem at some point in the future :D
Related
EDIT: Alex Martelli Gave me a great answer which I changed only slightly in order to get working properly for me
The answer to this problem for me was
public boolean Login2(String usernamein, String passwordin) {
DatastoreService datastore = DatastoreServiceFactory
.getDatastoreService();
Filter usernamefilter = new FilterPredicate("username",
FilterOperator.EQUAL, usernamein);
Query validuserquery = new Query("Users").setFilter(usernamefilter)
.setKeysOnly();
Entity theUser = datastore.prepare(validuserquery).asSingleEntity();
if (theUser == null) {
System.out.println("Username not found");
return false;
}
return true;
}
End of EDIT
Original Post
Okay so I have spent the entire day trying to do this and have tried my best to research it but I can't do it! :(
I feel like there is probably and easy answer but I can't work it out, I feel like I have tried Everything! please please please help D:
I have a Login section of code on its own .jsp page called Index.jsp
String username = "";
String password = "";
try {
if (request.getParameter("usernamein") != null && request.getParameter("passwordin") != null) {
username = (request.getParameter("usernamein"));
password = request.getParameter("passwordin");
if(login.Login2(username, password)){
response.sendRedirect("Race.jsp");
System.out.println("go to next page");
} else {//need username/password
out.println("your username or password is incorrect");
}
}
} catch (Exception e) {
out.println("problem in getting u an p error =" + e);
}
Part way through that code is the line (login.Login2(username, password))
that code calls a method in a class using java use bean thingy
the method it calls is this:
public boolean Login2(String usernamein, String passwordin) {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Filter usernamefilter = new FilterPredicate("username", FilterOperator.EQUAL, usernamein);
Query validuserquery = new Query("Users");
validuserquery.addProjection(new PropertyProjection("username", null));
System.out.println(validuserquery);
List<Entity> list = datastore.prepare(validuserquery).asList(FetchOptions.Builder.withLimit(100));
System.out.println(list);
for (Entity username : list){
System.out.println("username is equal to '"+username+"'");
if(username.equals(usernamein)){
return true;
}else
System.out.println("was not equal");
return false;
}
return false;
}
I'm trying to only go to the next page in the top code if the if statement is true, meaning that the username does exist, eventually I want it to only go to then next page if the username and password are both in the same entity i.e. the combination exists.
I hope you guys understand what i am trying to do and can help me
oh the System.out.println() for the username value outputs this:
username is equal to '<Entity [user("id")/Users(5910974510923776)]:
username = RawValue [value=[B#187c4d7]
>
'
If you need any more info just ask and i'll add it to the post :D ty
You would be best advised to query the datastore for just the username of interest...:
Query validuserquery = new Query("Users").
setFilter(new Query.FilterPredicate("username",
Query.FilterOperator.EQUAL,
usernamein)
).setKeysOnly();
Entity anyentity = datastore.prepare(validuserquery).asSingleEntity();
if(anyentity == null) {
System.out.println("was not equal");
return false;
}
return true;
This assumes there are no entities with duplicated username in your store (though you could deal with that by catching exception PreparedQuery.TooManyResultsException -- if that gets raised, it means you have more than one entity with that username, so that would be a return true case too:-).
The core idea is: getting every user entity and checking their usernames in your application code is really wasteful of resources (quite apart from the bugs in your code in this case) -- use queries to get only the relevant entity or entities, if any!-)
Try searching a bit more next time. It's not that hard, your issue was pretty easy. In any case :
Your query returns a full object, not just properties of your object. You need to do
entity.getProperty("username")
So that you see your property, not the full object.
More info here.
Hey Ive run into a little problem in my SQL/PHP/JAVA application Im hoping you guys can help :)
I have a java application that when run is connected to my website when the java application validates that it is running it talks to my website and my website assigns a session Id to both the java application and the website itself.
cool we good so far?
alright my java application sends data at regular intervals to a page called Dashboard.php what I would like to do is save the data into my Mysql table then when new data is received by Dashboard.php from my java application where the sessionID is the same I would like the table to update to the new data that was just received
here is the php i have so far although it doesnt work.
function update($script_name, $version, $runtime, $status, $ranged, $attack, $defense, $strength, $magic, $sessionID, $username)
{
global $db;
$sql = "SELECT * FROM Dashboard WHERE session_id = '$sessionID'";
try {
$results = $db->query($sql);
if ($results->rowCount() <= 0) {
$query = "INSERT INTO Dashboard (script_name, version, runtime, status, ranged, attack, defense, strength, magic, session_id, username) VALUES ('$script_name', '$version', '$runtime', '$status', '$ranged', '$attack', '$defense', '$strength', '$magic', '$sessionID', $username)";
$db->exec($query);
} else {
foreach ($results as $row) {
$timerunnew = $row['runtime'] + $runtime;
$v4new = $row['ranged'] + $range;
$v5new = $row['attack'] + $attack;
$v6new = $row['defense'] + $defense;
$v7new = $row['strength'] + $strength;
$v8new = $row['magic'] + $magic;
}
$db->exec("UPDATE Dashboard SET `runtime` = $timerunnew, `ranged` = $v4new, `attack` = $v5new, `defense` = $v6new, `strength` = $v7new, `magic` = $v8new WHERE session_id = '$sessionID'");
}
} catch (PDOException $ex) {
echo "fail";
}
}
Ive also tried experimenting with ON DUPLICATE KEY UPDATE value = VALUES(value) however I have had no luck does anyone have a solution? any help would be much appreciated
If this is the only way that records can be inserted into the Dashboard table, then it is impossible for two records to share the same session_id (save for a race hazard occurring between the SELECT and INSERT commands). In which case, you should:
Ensure that there is a UNIQUE key defined on session_id:
ALTER TABLE Dashboard ADD UNIQUE KEY (session_id);
Use INSERT ... ON DUPLICATE KEY UPDATE, ideally with a properly parameterised prepared statement:
$qry = $db->prepare('
INSERT INTO Dashboard (
script_name, version, runtime, status, ranged, attack,
defense, strength, magic, session_id, username
) VALUES (
:script_name, :version, :runtime, :status, :ranged, :attack,
:defense, :strength, :magic, :session_id, :username
) ON DUPLICATE KEY UPDATE
runtime = runtime + VALUES(runtime),
attack = attack + VALUES(status),
defense = defense + VALUES(defense),
strength = strength + VALUES(strength),
magic = magic + VALUES(magic)
');
$qry->execute([
':script_name' => $script_name,
':version' => $version,
':runtime' => $runtime,
':status' => $status,
':ranged' => $ranged,
':attack' => $attack,
':$defense' => $defense,
':strength' => $strength,
':magic' => $magic,
':session_id' => $sessionID,
':username' => $username
]);
I have an issue with python.
Here is my code.
http://pastebin.com/yRu5WGKd
Whenever I select Item or Pickaxe, it prints just fine. Anything below that won't print.. Please help!?!
Note: I also used pastebin because I find it easiest to read.
Your actual mistake is the 62nd line, if ItemType == 3 & ItemStr == 1: - it should start with elif, or it breaks your (really nasty) if-cascade.
Another potential problem: in all your comparisons, ie if ItemType == 1 & ItemStr == 1:, you are using bitwise and (&) when you should be using logical and (and).
Here is a rewritten version. It is less than half the length, data-driven, and makes it much easier to spot inconsistencies (did you mean 'Diamond' or 'Emerald' in your material types?):
class Item(object):
types = [
('Item', 'Item'),
('Pickaxe', 'ItemPickaxe'),
('Shovel', 'ItemSpade'),
('Axe', 'ItemAxe'),
('Hoe', 'ItemHoe'),
('Sword', 'ItemSword')
]
strengths = [
('Diamond', 'EnumToolMaterial.EMERALD'), # ?? You might want to doublecheck this...
('Gold', 'EnumToolMaterial.GOLD'),
('Iron', 'EnumToolMaterial.IRON'),
('Stone', 'EnumToolMaterial.STONE'),
('Wood', 'EnumToolMaterial.WOOD'),
]
javastring = 'public static final {type} {name} = new {type}({id}, {strength}).setItemName("{name}");'
#classmethod
def prompt_for_item(cls):
s = "Please enter your item's name:\n"
name = raw_input(s).strip()
types = ["[{}] {}".format(i,n[0]) for i,n in enumerate(cls.types, 1)]
s = "Please enter item type:\n{}\n".format('\n'.join(types))
type_ = int(raw_input(s)) - 1
s = "Please enter item id (unique int):\n"
id = int(raw_input(s))
strengths = ["[{}] {}".format(i,n[0]) for i,n in enumerate(cls.strengths, 1)]
s = "Please enter item strength:\n{}\n".format('\n'.join(strengths))
strength = int(raw_input(s)) - 1
return cls(name, type_, id, strength)
def __init__(self, name, type_, id, strength):
self.name = name
self.type = type_
self.id = id
self.strength = strength
def write_to_file(self, fname=None):
if fname is None:
fname = '{}.java'.format(self.name)
with open(fname, 'w') as outf:
cls = type(self)
outf.write(
cls.javastring.format(
type = cls.types[self.type][1],
name = self.name,
id = self.id,
strength = cls.strengths[self.strength][1]
)
)
def main():
it = Item.prompt_for_item()
it.write_to_file()
print 'File has been written'
if __name__=="__main__":
main()
When trying to update a record for one of my records I am using this code
private void UpdateCattleRecord(UpdateCattleRecord updateRecord){
mDB.beginTransaction();
String where = "_ID=";
String[] RecordToUpdate = {Cattle._ID};
Toast.makeText(this,"Updating Animal "+ RecordToUpdate, Toast.LENGTH_LONG).show();
try {
ContentValues CattleFieldsToUpdate = new ContentValues();
CattleFieldsToUpdate.put(Cattle.CATTLE_ANIMALID,updateRecord.getCattleName());
CattleFieldsToUpdate.put(Cattle.CATTLE_TYPE, updateRecord.getCattleType());
CattleFieldsToUpdate.put(Cattle.CATTLE_LOCATION, updateRecord.getCattleLocation());
CattleFieldsToUpdate.put(Cattle.CATTLE_DOB, updateRecord.getCattleDob());
CattleFieldsToUpdate.put(Cattle.CATTLE_DAM, updateRecord.getCattleDam());
CattleFieldsToUpdate.put(Cattle.CATTLE_SEX, updateRecord.getCattleSex());
mDB.update(Cattle.CATTLE_TABLE_NAME,CattleFieldsToUpdate, where, RecordToUpdate);
mDB.setTransactionSuccessful();
} finally {
mDB.endTransaction();
}
}
My log shows
Tag Database sqlite returned: error code =1, msg = near "=": syntax error
After researching this, I think I have everything in the right place but obviously I don't,
when I look at the next error in the log it's of course in 'red' and it shows me all the correct data,
03-27 15:15:29.291: E/Database(12011): Error updating date_of_birth=March 27, 2012 animaltype=Calf sex=F location=Eastern dam=601 animal_id=601A using UPDATE cattle SET date_of_birth=?, animaltype=?, sex=?, location=?, dam=?, animal_id=? WHERE _ID=
I've obviously got a problem with the value for _ID but can't seem to locate it. Can someone please point out where my Syntax error is?
Update
The problem occurred because I was failing to pass the actual value of the record (_ID) that I wanted to update. Once I passed that as a parameter to my updaterecords function the update went as scheduled.
Thanks for the input, it helped me narrow down what I was doing wrong.
Check your database creation, your probably have a column named _id(although you refer to it by _ID, its name is _id) and not _ID:
String where = "_id= ?"; // ? represent the value from the selection arguments String array
or better:
String where = Cattle._ID + "= ?";
Edit:
In your where selection argument you put:
String[] RecordToUpdate = {Cattle._ID};
you probably want to put in there some id you get from somewhere(of the record you want to update, a long number), right now you're doing:
WHERE _ID = _ID (or _id)
and this will fail.
try:
mDB.update(Cattle.CATTLE_TABLE_NAME,CattleFieldsToUpdate, "_ID="+Cattle._ID, null);
try:
mDB.update(Cattle.CATTLE_TABLE_NAME,CattleFieldsToUpdate, "_ID="+updateRecord.getId(), null);
I am trying to use ehcache in my project.. i have specified the following properties in hibernate config file -
config.setProperty("hibernate.cache.provider_class","org.hibernate.cache.EhCacheProvider");
config.setProperty("hibernate.cache.provider_configuration_file_resource_path","ehcache.xml");
config.setProperty("hibernate.cache.use_second_level_cache","true");
config.setProperty("hibernate.cache.use_query_cache","true");
Now i am still not sure whether the results are coming from DB or the cache..
I looked around and found - Hibernate second level cache - print result where the person is suggesting HitCount/Misscount API's
However when i tried using it the hitcount and miss count is always returned 0... here's my code
String rName = "org.hibernate.cache.UpdateTimestampsCache";
Statistics stat =
HibernateHelper.getInstance().getFactory().getStatistics();
long oldMissCount =
stat.getSecondLevelCacheStatistics(rName).getMissCount();
long oldHitCount =
stat.getSecondLevelCacheStatistics(rName).getHitCount();
UserDAO user = new UserDAO();
user.read(new Long(1)); long
newMissCount =
stat.getSecondLevelCacheStatistics(rName).getMissCount();
long newHitCount =
stat.getSecondLevelCacheStatistics(rName).getHitCount();
if(oldHitCount+1 == newHitCount &&
oldMissCount+1 == newMissCount) {
System.out.println("came from DB"); }
else if(oldHitCount+1 == newHitCount
&& oldMissCount == newMissCount) {
System.out.println("came from cache");
}
Please let me know if i am using it wrong.. and what should be the rName(region Name) in this case..
Is there any other way of determining whether the second level cache is working ??
Thanks
You need to enable statistics collection:
config.setProperty("hibernate.generate_statistics", "true");