I have a controller that calls a JpaRepository derived query method, I thought it was supposed to be case sensitive by default and from google I've only found options to add case insensitivity to the query, but not the case sensitivity. In my code it finds and returns rows from database regardless of case. Is it a bug or i don't know something ?
Controller code:
System.out.println(nickname);
User invitedUser = userService.findByNickname(nickname);
System.out.println(invitedUser);
JpaRepository code:
Optional<User> findByNicknameEquals(String nickname);
I have tried just findByNickname but result was the same
UserService code:
public User findByNickname(String nickname){
Optional<User> result = userRepository.findByNicknameEquals(nickname);
User user;
if(result.isPresent()){
user = result.get();
}else{
user = null;
}
return user;
}
what gets printed by the sout() from controller:
Fixed by changing default charset and collation on database tables:
ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE utf8_bin;
before this I had this charset, this is what made it ignore case.
ENGINE=InnoDB DEFAULT CHARSET=latin1;
Related
I am currently trying to implement Spring's ACLs into my existing application.
Sadly i am stuck at a specific point which seems to be caused by my UserDetailsService.
The problem/error is the following when i call the createAcl() function of the
MutableAcl class like this:
public void addPermission(long objectId, Sid recipient, Permission permission, Class clazz) {
MutableAcl acl;
ObjectIdentity oid = new ObjectIdentityImpl(clazz.getCanonicalName(), objectId);
try {
acl = (MutableAcl) mutableAclService.readAclById(oid);
} catch (NotFoundException nfe) {
acl = mutableAclService.createAcl(oid);
}
acl.insertAce(acl.getEntries().size(), permission, recipient, true);
mutableAclService.updateAcl(acl);
}
Inside of this function a new ObjectIdentity is created, if this class instance does not yet have one. A new PrincipalSid is created from the current Authentication object for this purpose (saved inside the ACL_SID table). Like this:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
PrincipalSid sid = new PrincipalSid(auth);
this.createObjectIdentity(objectIdentity, sid);
The problem occurs when it tries to save the entry into the ACL_SID table which is defined as this:
CREATE TABLE IF NOT EXISTS ACL_SID (
id BIGSERIAL NOT NULL PRIMARY KEY,
principal BOOLEAN NOT NULL,
sid VARCHAR(100) NOT NULL,
CONSTRAINT UNIQUE_UK_1 UNIQUE(sid,principal)
);
As you can see the sid is a VARCHAR with 100 characters. My custom User class contains a few properties which are mostly converted to a String representation, which causes the PrincipalSid to be longer than 100 characters. Now the first obvious solution would be to just change the toString method to only return the most essential values.
Still this seems kinda "hacky" to me. Is there a better solution?
The sid column in ACL_SID table should only contain the username, not the entire user object with its properties. To create a correct instance of PrincipalSid, make sure at least one of following is true:
auth.getPrincipal() returns an instance of UserDetails interface.
auth.getPrincipal().toString() returns the username.
I am using ServiceStack.Ormlite, and also make heavy use of the automatic handling of enums whereby they are stored in the db as strings but retrieved and parsed nicely back into Enums on retrieval, so I can do easy type-comparison - say, for a property "UserRole" in the db/table class "User" of enum type "UserRoleEnum" (just for demonstration).
This works great.. until I want to use the enum property to define a multi-column unique constraint
CompositeIndexAttribute(bool unique, params string[] fieldNames);
like:
[CompositeIndex(true, nameof(UserId), nameof(UserRole)]
public class User
{
public long UserId {get;set;}
public UserRoleEnum UserRole {get;set;
}
(as per :
How to Create Unique Constraint with Multiple Columns using ServiceStack.OrmLite? ).
At which time i get:
System.Data.SqlClient.SqlException
Column 'UserRole' in table 'User' is of a type that is invalid for use as a key column in an index.
I currently see options as:
a) Define UserRole as a string (isntead of UserRoleEnum ) in the table entity class and lose the Enum use.... having to manually test the value each time to confirm that the db value is one that i expect in my business logic later
b) Continue to use UserRoleEnum but lose the ability to declare multicolumn uniqueconstraints using the class attribute, and probably have to create these manually using a subsequent db migration script?
Is there any way to make the enums and the multicolumn constraint play nicely, out of the box?
This issue was because enum properties were using the default string definition fallback of VARCHAR(MAX) which SQL Server doesn't let you create indexes on whereas the column definition of a string property is VARCHAR(8000).
This issue is now resolved from this commit which now uses the VARCHAR(255) string definition of the EnumConverter Type Converter. This change is available from v4.5.5 that's now available on MyGet.
Otherwise you can also change the size of the column definition to match a string property by adding a [StringLength] attribute, e.g:
[CompositeIndex(true, nameof(UserId), nameof(UserRole))]
public class User
{
public long UserId { get; set; }
[StringLength(8000)]
public string UserRole { get; set; }
}
I have a users table and I am trying to use annotated Queries in spring boot to get a result set. I am able to get result set as a list, but that does not have field names. How do I get the result set with field name as key and value pairs?
Current response [[1,"Jay"]] , what I want to do is {"id":1,"Name":"Jay"}
-----Here is my repository class-----
#Repository
public interface UsersauthRepository2 extends JpaRepository<Users2,Long> {
#Query("select id,name,email from Users u where LOWER(email) = LOWER(:email) and LOWER(u.password) = LOWER(:password)")
List<Users2> querybyemail(#Param("email") String email,#Param("password") String password);
}
The request doesn't return fields names.
If you need to get them :
You have them already as method argument
You need to use reflection.
Good luck
I am trying to use a table for my Users and separate table for users' Projects in my database. However I want the names of the fields to be different for user id. What I want to take the id from the 'Users' table; and while saving the created project to the database, use that (user) id as created_by_id in Projects table.
public function store(CreateProjectRequest $request)
{
$project = new Project($request->all());
Auth::user()->projects()->save($project);
// Project::create($request->all());
return redirect('pages/home');
}
Also in Users.php, I added:
public function projects()
{
return $this->hasMany('App\Project');
}
The commented field is working on its own. However, I guess my problem arises because when I comment that line again, and add the other two lines ($project... and Auth::user... bits), I guess it is assuming I have a field in the Projects table named id.
I thought I would work around this problem with changing the primary key but I couldn't find how to take the Auth::user()->id; and make it write that value in created_by_id in a secure way. This is what I found though:
class Project extends Eloquent {
protected $primaryKey = 'created_by_id';
}
Edit: I don't think changing the primary key is my solution.
You can pass a second and third parameter to hasMany() method to specify the keys to use. Documentation
public function projects()
{
return $this->hasMany('App\Article','userid','created_by');
}
I am new to Grails. I installed Grails 2.4.4 version and Spring Tool Suite.
I created Grails project and domain ,controller classes. But i am getting all the fields as mandatory by default and "id" is not generated. Need some help.
Domain Class:
package org.example.pomorodo
class Task {
String summary
String details
Date dateCreated
Date deadLine
Long timeSpent=0L
static constraints = {
}
}
Controller Class:
package org.example.pomorodo
class TaskController {
static scaffold =Task
}
Do you mean you can't access the "id" property after saving your domain object with GORM? Or just that the generated code doesn't have an "id" property explicitly defined? If it's the latter, don't worry. The "id" property is automatically injected by metaprogramming black-magic by the framework. If it's the former, something else is wrong, as you should definitely have a valid "id" after saving a domain object.
On the mandatory fields: Use the constraints block to toggle fields to nullable = true. Example:
package org.example.pomorodo
class Task {
String summary
String details
Date dateCreated
Date deadLine
Long timeSpent=0L
static constraints = {
summary(nullable:true)
details(nullable:true)
}
}
You can also modify default constraints globally. See the constraints documentation for more details.
Recently I got a query regarding mapping a database table which do not have any id and version. For example the table have two varchar fields username and password nothing more than that.
Although it was something strange for me that table doesn’t have the id field. The good thing is that the username is a primary key in the table and this is not auto incremented user want to create it by his own method.
The good thing about grails is, in most of the cases you get your answer in the docs http://grails.org/doc/latest/ . So in this case we just need to change the id field in grails domain like this
class Test {
String username
String password
static mapping = {
id name: 'username'
version false
id generator: 'assigned'
}
static constraints = {
username(nullable: true)
}
}