i got error in my codes like this :
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: Syntax error: Encountered ":" at line 1, column 42. Error Code: -1 Call: select userLevelId from USERS where id = :id Query: DataReadQuery(sql="select userLevelId from USERS where id = :id ")
and my code :
public String cek() { if (tmp.equals(tmp2)) {
y =1;
level = getItems().toString(); }
.....
.....
}
public List<Users> getItems() {
if (y.equals(1)) {
y=0;
tmp = tmp.trim();
return em.createNativeQuery("select userLevelId from USERS where id = :id")
.setParameter("id", tmp).getResultList(); }
}
so where's my fault ?
can anyone help me ?
thx b4
Main Problem
Native queries don't use named parameter syntax (:id). Use prepared statement syntax with the ?. Then use. setParameter( indexOf?, value ) . For example
...("select userLevelId from USERS where id = ?")
...setParameter(1, tmp)
Other Notes
Don't do your querying in the getter if the getter is part of the property binding. For instance if you have List<User> items as a bean property, don't do any business logic or in your case querying in the getter. The getter may be called for a few number of reason, apart from what you expect. Instead you can initialize it in a #PostConstruct method or in your constructor. If you need to update the list, have a listener method that will update it, and directly call that method
A common practice is to separate the business layer and web layer (the managed bean). The business layer can be an EJB in which you inject into the managed bean
Related
I am using JHipster 3.3. In the generated "entity"-dialog.html, I noticed the tag jhi-alert-error element will display server validation error so for example if a field is mandatory as specified in entity JPA class like
#NotNull
private String name;
Then error message for that field will be returned after clicking the Submit button if value of the field is empty.
So questions:
How is jhi-alert-error implemented? I can't seem to see its implementation
I tried tweaking JPA annotation to make a field unique BUT this time no error message will be displayed in jhi-alert-error if I break the unique constraint by adding 2 records having the same value for the field,
E.g.
// note 'unique=true' below
#NotNull
#Column(name = "name", unique=true)
private String name;
or
#Table(name="Module", uniqueConstraints = #UniqueConstraint(columnNames = "Name"))
public Class Module implements Serializable { ...
So how would I go about implementing my own server side form validation so error messages will be displayed in jhi-alert-error when the unique constraint of a field is broken after clicking the Submit button?
Thanks in advance,
I'm using a slightly older version of jhipster (2.26), so there could be some differences in the code. To answer your first question the jhi-alert-error is a custom Angular directive, have a look at the alert.directive.js file and the jhAlertError directive (should appear after the jhAlert directive). The directive expects the httpResponse.data object to be the ErrorDTO server side object.
To add custom error messages, you need to return an ErrorDTO object and the directive will display the message. To do this you need to throw an exception and ensure that the spring AOP - ExceptionTranslator is configured to catch it. If you don't want to create new custom Exceptions, you can use the CustomParameterizedException:
#RequestMapping(value = "/pizzas",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<Pizza> create(#RequestBody Pizza pizza) throws URISyntaxException {
if(pizza.isDisgusting()){
throw new CustomParameterizedException("Sorry, your pizza recipe is horrible");
}
log.debug("REST request to save Pizza : {}", pizza);
if (pizza.getId() != null) {
return ResponseEntity.badRequest().header("Failure", "A new pizza cannot already have an ID").body(null);
}
Pizza result = pizzaRepository.save(pizza);
return ResponseEntity.created(new URI("/api/pizzas/" + pizza.getId())).body(result);
}
I have a simple query as follows "select * from USERS". I also use Pageable to enable pagination.
This query may have optional predicates based on the given parameters being null or not.
For example if "code" parameter is given and not null, then the query becomes
"select * from USERS where code = :code";
As far as I know I cannot implement this using #Query annotation. I can implement a custom repository and use EntityManager to create a dynamic query.
However, I am not sure how I can integrate "Pageable" with that to get back paginated results.
How can I achieve this?
This is very easy to do in Spring Data using QueryDSL (as alternative to the criteria API). It is supported out of the box with the following method of QueryDSLPredicateExecutor where you can just pass null as the Predicate if no restrictions are to be applied:
Page<T> findAll(com.mysema.query.types.Predicate predicate,
Pageable pageable)
Using QueryDSL may not be an option for you however if you look at the following series of tutorials you might get some ideas.
http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-nine-conclusions/
The scenario you have is actually discussed by the author in the comments to part 9 of his guide.
Getting page results for querydsl queries is somehow complicated since you need two queries: one for the total number of entries, and one for the list of entries you need in the page.
You could use the following superclass:
public class QueryDslSupport<E, Q extends EntityPathBase<E>> extends QueryDslRepositorySupport {
public QueryDslSupport(Class<E> clazz) {
super(clazz);
}
protected Page<E> readPage(JPAQuery query, Q qEntity, Pageable pageable) {
if (pageable == null) {
return readPage(query, qEntity, new QPageRequest(0, Integer.MAX_VALUE));
}
long total = query.clone(super.getEntityManager()).count(); // need to clone to have a second query, otherwise all items would be in the list
JPQLQuery pagedQuery = getQuerydsl().applyPagination(pageable, query);
List<E> content = total > pageable.getOffset() ? pagedQuery.list(qEntity) : Collections.<E> emptyList();
return new PageImpl<>(content, pageable, total);
}
}
You have to use querydsl and build your where depending on not null parameter for example
BooleanBuilder where = new BooleanBuilder();
...
if(code != null){
where.and(YOURENTITY.code.eq(code));
}
and after execute the query
JPAQuery query = new JPAQuery(entityManager).from(..)
.leftJoin( .. )
...
.where(where)
and use your own page
MaPage<YOURENTITY> page = new MaPage<YOURENTITY>();
page.number = pageNumber+1;
page.content = query.offset(pageNumber*pageSize).limit(pageSize).list(...);
page.totalResult = query.count();
I create MyPage like that
public class MaPage<T> {
public List<T> content;
public int number;
public Long totalResult;
public Long totalPages;
...
}
it works but if in your query you got a fetch then you gonna have this warning
nov. 21, 2014 6:48:54 AM org.hibernate.hql.internal.ast.QueryTranslatorImpl list
WARN: HHH000104: firstResult/maxResults specified with collection fetch; applying in memory!
and it will slow down your request So the solution is to get ride of the fetch and define a #BatchSize(size=10) and use Hibernate.initialize(....) to fetch data in collections and other object type.
Display data from related entities to avoid the lazy initialization exception with setting up #BatchSize
How to execute a JPAQuery with pagination using Spring Data and QueryDSL
The information here is obsolete. Have your Repository implement the QueryDslPredicateExecutor and paging comes for free.
I'm using a function to allow query composition from Web UI and I would to implement paging functionality which it will be available for dataBound controls such as ObjectDataSource, gridView, etc:
public class MyClass<TEntity> where TEntity : class
{
FakeEntities xxx = new FakeEntities();
public IEnumerable<TEntity> Get(Func<IQueryable<TEntity>, IQueryable<TEntity>> queryExpression)
{
var query = xxx.Set<TEntity>();
return queryExpression(query).ToList();
}
public int Count()
{
// What Can I return?
}
}
// **** USAGE ****
MyClass<User> u = new MyClass<User>();
var all = u.Get(p => p.Where(z => z.Account == "Smith").OrderBy(order => order.IdOther).Skip(1).Take(2));
The above query use Take and Skip function, so can I get real count of my entities? Obviously I must return Query Count without modifying filter expression.
I found this solution: Get count of an IQueryable<T>
However I get targetInvocationException with inner message {"This method supports the LINQ to Entities infrastructure and is not intended to be used directly from your code."}
I know my request could be freak-abnormal, because best practice should to impose to move "presentation needs" to some wrap class and that's is what I'll do. So I don't need anymore to get Count entities on my business logic class.
That's just UI concern only.
Thank you the same.
I have been trying desperately to delete an item from the database but have so far been unable to get it to work. The error message I see is this one:
"The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable."
I am using EF4.1, with EDMX (Database first) and POCO objects. I have a repository for each type and a general repository that implements the base methods.
The specific problem is when I want to delete an item. Deleting the children is not a problem - everything works perfectly - the problem is when I come to delete the entity itself.
Consider the following model. I have an entity "Foo" which has a 1 to many relationship with "Bar". I call the following method in my repository:
public override void Delete(Models.Foo entity)
{
//Load the child items...
base.Context.Entry(entity).Collection(x => x.Bars).Load();
//Bar
BarRepository barRep = new BarRepository();
foreach (var item in entity.Bars)
{
var obj = barRep.GetById(item.ID);
barRep.Delete(obj);
}
barRep.Save();
//First attempt
//base.Delete(entity);
//base.Save();
//Have to resort to some SQL
base.ExecuteSqlCommand(string.Format("delete from Foo where ID = {0}", entity.ID));
}
The GenericRepository "Delete" method is:
public virtual void Delete(T entity)
{
_entities.Set<T>().Remove(entity);
}
The GenericRepository "Save" method is simply:
public virtual void Save()
{
_entities.SaveChanges();
}
What I would like to get to work is this:
//First attempt
//base.Delete(entity);
//base.Save();
But unfortunately the only way (currently) for me to delete the item is to run some SQL which just calls _entities.Database.ExecuteSqlCommand(SQL).
I've read a lot of things but nothing seems to work. I would really appreciate some help in trying to understand what is going on.
Thanks,
Jose
Im using subsonic 2.2
I tried asking this question another way but didnt get the answer i was looking for.
Basically i ususally include validation at page level or in my code behind for my user controls or aspx pages. However i haev seen some small bits of info advising this can be done within partial classes generated from subsonic.
So my question is, where do i put these, are there particular events i add my validation / business logic into such as inserting, or updating. - If so, and validation isnt met, how do i stop the insert or update. And if anyone has a code example of how this looks it would be great to start me off.
Any info greatly appreciated.
First you should create a partial class for you DAL object you want to use.
In my project I have a folder Generated where the generated classes live in and I have another folder Extended.
Let's say you have a Subsonic generated class Product. Create a new file Product.cs in your Extended (or whatever) folder an create a partial class Product and ensure that the namespace matches the subsonic generated classes namespace.
namespace Your.Namespace.DAL
{
public partial class Product
{
}
}
Now you have the ability to extend the product class. The interesting part ist that subsonic offers some methods to override.
namespace Your.Namespace.DAL
{
public partial class Product
{
public override bool Validate()
{
ValidateColumnSettings();
if (string.IsNullOrEmpty(this.ProductName))
this.Errors.Add("ProductName cannot be empty");
return Errors.Count == 0;
}
// another way
protected override void BeforeValidate()
{
if (string.IsNullOrEmpty(this.ProductName))
throw new Exception("ProductName cannot be empty");
}
protected override void BeforeInsert()
{
this.ProductUUID = Guid.NewGuid().ToString();
}
protected override void BeforeUpdate()
{
this.Total = this.Net + this.Tax;
}
protected override void AfterCommit()
{
DB.Update<ProductSales>()
.Set(ProductSales.ProductName).EqualTo(this.ProductName)
.Where(ProductSales.ProductId).IsEqualTo(this.ProductId)
.Execute();
}
}
}
In response to Dan's question:
First, have a look here: http://github.com/subsonic/SubSonic-2.0/blob/master/SubSonic/ActiveRecord/ActiveRecord.cs
In this file lives the whole logic I showed in my other post.
Validate: Is called during Save(), if Validate() returns false an exception is thrown.
Get's only called if the Property ValidateWhenSaving (which is a constant so you have to recompile SubSonic to change it) is true (default)
BeforeValidate: Is called during Save() when ValidateWhenSaving is true. Does nothing by default
BeforeInsert: Is called during Save() if the record is new. Does nothing by default.
BeforeUpdate: Is called during Save() if the record is new. Does nothing by default.
AfterCommit: Is called after sucessfully inserting/updating a record. Does nothing by default.
In my Validate() example, I first let the default ValidatColumnSettings() method run, which will add errors like "Maximum String lenght exceeded for column ProductName" if product name is longer than the value defined in the database. Then I add another errorstring if ProductName is empty and return false if the overall error count is bigger than zero.
This will throw an exception during Save() so you can't store the record in the DB.
I would suggest you call Validate() yourself and if it returns false you display the elements of this.Errors at the bottom of the page (the easy way) or (more elegant) you create a Dictionary<string, string> where the key is the columnname and the value is the reason.
private Dictionary<string, string> CustomErrors = new Dictionary<string, string>
protected override bool Validate()
{
this.CustomErrors.Clear();
ValidateColumnSettings();
if (string.IsNullOrEmpty(this.ProductName))
this.CustomErrors.Add(this.Columns.ProductName, "cannot be empty");
if (this.UnitPrice < 0)
this.CustomErrors.Add(this.Columns.UnitPrice, "has to be 0 or bigger");
return this.CustomErrors.Count == 0 && Errors.Count == 0;
}
Then if Validate() returns false you can add the reason directly besides/below the right field in your webpage.
If Validate() returns true you can safely call Save() but keep in mind that Save() could throw other errors during persistance like "Dublicate Key ...";
Thanks for the response, but can you confirm this for me as im alittle confused, if your validating the column (ProductName) value within validate() or the beforevalidate() is string empty or NULL, doesnt this mean that the insert / update has already been actioned, as otherwise it wouldnt know that youve tried to insert or update a null value from the UI / aspx fields within the page to the column??
Also, within asp.net insert or updating events we use e.cancel = true to stop the insert update, if beforevalidate failes does it automatically stop the action to insert or update?
If this is the case, isnt it eaiser to add page level validation to stop the insert or update being fired in the first place.
I guess im alittle confused at the lifecyle for these methods and when they come into play