I'm fairly new to both Java EE and MVC. I have to develope a web application using Servlet, JSP, JB and EJB. As most applications mine too needs to interact with a RDBMS.
A friend of mine sent me a wep App he developed in which he has a
Serializable DbManager class
in which a
private transient Connection
exists as a member variable.
In all his servlets in which he needs DB access he has a DbManager variable. It is instantiate in the init method of the servlet and it is retrived like this :
this.manager = (DbManager)super.getServletContext().getAttribute("dbmanager");
All the queries are implemented as public methods of the DbManager Class.
I was wondering if this is a good way to implement such needs or if there is a better way to handle Db access and queries execution. I tought of implementing business logic and thus DB access as public methods in my EJBs.
Thanks for any help!
Homemade DbManager style classes are redundant when you are living in a JavaEE environment. You can make use of JPA for performing all your database queries from a stateless session bean that forms the "controller" part of your MVC architecture:
#Stateless
public class OrderController {
#PersistenceContext
private EntityManager em;
public void addNewOrder(Order order) {
em.persist(order)
}
public List<Order> findAllOrders() {
TypedQuery<Order> findAllOrdersQuery = em.createQuery("select o from Order o", Order.class);
return findAllOrdersQuery.list();
// In practice you would add pagination to this.
// It's not practical to return a million orders to your view.
}
...
}
This stateless EJB manages all transactions on your behalf, so you don't normally need to be concerned with beginning, committing and/or rolling back transactions.
The Order class is a component of your "model":
#Entity
public class Order {
#Id
private long id;
#Column
private String orderNumber;
#Column
private String description;
// other attributes
...
Order() { }
public Order(String orderNumber, String description) {
this.orderNumber = orderNumber;
this.description = description;
}
// setters and getters
...
// you must also override equals() and hashCode()
}
You will see many examples where developers introduce a so called DAO layer into their controller, but this is considered redundant as the EntityManager essentially satisfies that contract.
I am validating a input class using Java validation api and hibernate validator.
i have created few custom annontation for some business validation and i am using these annotation on the input class. below is an example of such annotation validator -
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class DBColumnConstraintValidator implements ConstraintValidator<DatabaseColumnConstraint, Object> {
private DBColumnConstraintValidator databaseColumnConstraint;
private final List<DatabaseConstraintValidationStep> steps = new ArrayList<DatabaseConstraintValidationStep>();
#Override
public void initialize(DBColumnConstraintValidator databaseColumnConstraint) {
}
#Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
//Validation logic
}
}
I want to use some data for my validation logic inside isValid() method and this data is common and will be used by few other validator classes as well.
is there any way to set or make that common data available to isValid() method?
If you are using CDI or Spring, you can simply use dependency injection (e.g. using #Inject) within your constraint validator implementation to obtain whatever contextual service or data your need.
I have ignored a column through fluent API but want to populate that property while executing stored procedure using some logic. But it is not mapping the ignored column property. Please let me know if there is any way to do this in Entity framework code first.
I've faced with the same problem recently. The only solution I found is a class hierarchy:
public class MyEntityBase {
public int Id { get; set; }
}
public class MyEntity: MyEntityBase {
...
}//This class is mapped to DB with a fluent API and does not contain ignored property.
//Also it does not have derivative classes, so EF will not create class inheritance in DB.
public class DerivedEntity: MyEntityBase {
public int IgnoredProperty { get; set; }
}//Use this class while executing stored procedures
P.S. Do not mark class MyEntityBase as ABSTRACT - EF will map this relationship as database inheritance.
I'm using the NewtonSoft JSON.NET library for serializing the following class where DTOBase can hold derived instances.
public class Command
{
public DTOBase CommandDTO { get; set; }
}
Per this article you need to include the JsonProperty attribute so that the derived instances get deserialized properly
public class Command
{
[JsonProperty(TypeNameHandling = TypeNameHandling.All)]
public DTOBase CommandDTO { get; set; }
}
The question is whether there is any other way besides using an attribute to get the same result? I would prefer to not be coupled to the NewtonSoft library and json serialization in particular at the class level. Is there a way to specify some settings on the Serialize/Deserialize methods of the library at all to get the same result?
The TypeNameHandling property can be set on JsonSerializerSettings when you call JsonConvert.SerializeObject(value, settings).
If you only want the name included for derived objects set TypeNameHandling to TypeNameHandling.Auto.
I'm trying implement Data Annotation to my Linq to SQL objects. The .dbml file is generated and I'm not sure how to add data annotation to the objects without touching the generated source code.
I tried to add data annotations to the a separate partial class of the object, but its not recognizing it, no Intelli sense either.
As I said in my original answer to this question, you should use an interface. The answer posted after mine (which was marked as Accepted) said to use a class. This is not as good. An interface is a better option for the following reasons:
If there is a mismatch between the name in your LINQ class and the name in your interface, the compiler will flag it for you
An interface can not be instantiated, so this protects class users from accidentally instatntiating the metadata type
If you use Resharper (or similar), the interface can be automatically extracted from the LINQ class
An interface is less verbose than an empty class
If you program against interfaces rather than classes (which is a good practice), then you've already got an interface you can use as your metadata type
For a class called, say "User", create an interface for it (say 'IUser'), and then update the definition of your partial User class as follows:
[MetadataType(typeof(IUser))]
public class User : IUser
Then, in your IUser interface, add appropriate Data Annotation attributes to the properties:
[Required]
[StringLength(50, ErrorMessage = "Username cannot exceed 50 characters")]
string Username { get; set; }
For a class called, say "User", create an interface for it (say 'IUser'), and then update the definition of your partial User class as follows:
[MetadataType(typeof(IUser))]
public class User : IUser
Then, in your IUser interface, add appropriate Data Annotation attributes to the properties:
[Required]
[StringLength(50, ErrorMessage = "Username cannot exceed 50 characters")]
string Username { get; set; }
Linq to SQL generates object classes as partial. An easy way to implement data annotations is to create your own partial class of the object, place the [MetadataType(typeof(YourDataAnnotationClass))] on the partial class you created.
Example:
// Linq to SQL Class
public partial class Article
{
public string Title { get; set; }
...... etc
}
Create your own MetaData class with Metadata for each field you want to validate
public class MyMetaDataClass
{
[Required]
[Range(5,20)]
public string Title { get; set; }
}
Create a Partial Class for the Object class you want to add metadata to, in this case Articles class:
[MetadataType(typeof(MyMetaDataClass))]
public partial class Article { }
Note: you don't need to specify anything in the class, just the metadata type.
Thanks,but the problem is MS define the prototype of MetadataTypeAttrubute as
[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class MetadataTypeAttribute : Attribute
So, you had to use class but not interface
From China
Forest Lee: 李晓强
xiaoqianglinsen#163.com (MSN)
lixiaoqiang#webservice.com.cn