DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Data Engineering Topics

article thumbnail
JPA Join Table With Additional State
JPA has its puzzles and from time to time it is useful to write down that tricky solution for our mapping needs.This entry describes a ManyToMany relationship with an additional state in the intermediate table. All my examples are related to the Arena-PUJ project, the pet project I am hard working nowadays. Arena is an online system to manage academic competitions, and within its several tables and mappings, there is a corner case I will explain below. First, let me define the entities and its relationship for modeling the data of the Institutions X Competition relationship. Institutions X Competitions We have two entities, with a ManyToMany relationship: Competition: is a virtual competition where students apply for the best academic homework of a region (a city, a state or even a country). Several competitions happen at same time in different places, sponsored and organized by different institutions. Institution: a company, a JUG or a school. It models the competitors' university, the JUG organizing a competition or a Company sponsoring a competition. Institutions have roles in a competition. The problem: institution roles are dynamic Competitions happens annually and for different competitions a same institution can have different roles. The classical example is about sponsorship: a company that was partner in the 2008 becomes platinum sponsor in 2009. The modeling of roles of the institutions is dynamic - institutions can have different roles in different competitions. The solution: a Join Table with an additional state The relation between competitions and institutions is a @ManyToMany relationship but we cannot just annotate the entities. In order to support the dynamic roles of institutions we need to customize the relation table, what means we need to add additional columns in the join table, as demonstrated in the diagram below. Implementing the join table with JPA 1.x Annotations The join table has @ManyToOne relationships with the two entities and also an enumeration with the possible roles an institution can have in a competition. In order to work as a real join table, you must use a @ClassId as composite primary key of the join table. You can check out the complete source code from here, but the relevant parts are in the below fragments. The join table: @Entity @IdClass(PujInstitutionRoles_PK.class) public class PujInstitutionRoles implements Serializable { public enum Role { SCHOOL, PUJ_OWNER, SPONSOR, PARTNER } @Enumerated(EnumType.STRING) @Column(columnDefinition = "VARCHAR(20)") private PujInstitutionRoles.Role role; @Id @ManyToOne @PrimaryKeyJoinColumn(name = "INSTITUTION_ACRONYM", referencedColumnName = "acronym") private PujInstitutionEntity institution; @Id @ManyToOne @PrimaryKeyJoinColumn(name = "COMPETITION_NAME", referencedColumnName = "name") private PujCompetitionEntity competition; } The composite primary key of the join table public class PujInstitutionRoles_PK implements Serializable { private String institution; private String competition; } * Notice that @IdClass is a simple Java Type, not an Entity. * Important detail: the field names of the ID Class should match the names of the ID fields of the Join Table. The Institution model * @Entity public class PujInstitutionEntity implements Serializable { @Id @Column(length = 20) private String acronym; } The Competition model * @Entity public class PujCompetitionEntity implements Serializable { @Id @Column(length = 12) private String name; } * In my real model I also have the mapping from the entities to the join table, but I ommited here to make the examples shorter. Using the model: our join serves for two basic purposes: to maintain the relationship between institutions and competitions and also to allow us to query that relationship. The insertion of a new relationship is a normal insert operation, but the queries on the join table requires the usage of named queries. How to find competitions by institutions? The proper way to find this relationship is to define a @NamedQuery where I can find institutions by competitions, as demonstrated below. I am using some constants to facilitate the reference to the queries in other classes. @NamedQueries( { @NamedQuery(name = PujCompetitionEntity.SQL.FIND_BY_INSTITUTION, query = "SELECT roles.competition FROM PujInstitutionRoles roles JOIN roles.institution inst WHERE inst.acronym=:" + PujCompetitionEntity.SQL.PARAM_INSTITUTION_ACRONYM) }) @Entity public class PujCompetitionEntity implements Serializable { public static final String FIND_BY_INSTITUTION = "findCompetitionByInstitution"; public static final String PARAM_INSTITUTION_ACRONYM = "institutionAcronym"; } Example of usage: @Stateless public class PujCompetitionFacadeImpl { @PersistenceUnit(name = "arenapuj") protected EntityManagerFactory emf; public Collection findByInstitution(String acronym, int start, int max) throws IllegalStateException, IllegalArgumentException { EntityManager manager = emf.createEntityManager(); try { Query query = manager .createNamedQuery(PujCompetitionEntity.FIND_BY_INSTITUTION); query.setParameter(PujCompetitionEntity.PARAM_INSTITUTION_ACRONYM, acronym); query.setFirstResult(start); query.setMaxResults(max); return getResultList(query); } finally { if (manager != null && manager.isOpen()) { manager.close(); } } } } Some live examples: listing all pairs of Institution X Competition finding all competitions linked to CEJUG Summary The solution for the above problem is predicted in the JPA specification but the annotations details for implementing a Join Table with an additional state is not so intuitive (IMO). I documented the solution for a future quick reference and I hope you can also benefit from that - if you disagree of my modeling or if you have any good suggestion, please give me your feedback. From http://weblogs.java.net/blog/felipegaucho
October 26, 2009
by Felipe Gaúcho
· 25,875 Views
article thumbnail
Understanding the NHibernate Type System
This article is taken from NHibernate in Action from Manning Publications. This article delves into the NHibernate type system. For the table of contents, the Author Forum, and other resources, go to http://www.manning.com/kuate/. It is being reproduced here by permission from Manning Publications. Manning ebooks are sold exclusively through Manning. Visit the book's page for more information. Softbound print: February 2009 | 400 pages ISBN: 1932394923 Use code "dzone30" to get 30% off any version of this book. Entities are the coarse-grained classes in a system. You usually define the features of a system in terms of the entities involved: “the user places a bid for an item” is a typical feature definition that mentions three entities - user, bid and item. In contrast, value types are the much more fine grained classes in a system, such as strings, numbers, dates and monetary amounts. These fine grained classes can be used in many places and serve many purposes; the value type string can store email address, usernames and many other things. Strings are simple value types, but it is possible (but less common) to create value types that are more complex. For example, a value type could contain several fields, like an Address. So how do we differentiate between value types and entities? From a more formal standpoint, we an say an entity is any class whose instances have their own persistent identity, and a value type is a class who’s instances do not. The entity instances may therefore be in any of the three persistent lifecycle states: transient, detached, or persistent. However, we don’t consider these lifecycle states to apply to the simpler value type instances. Furthermore, because entities have their own lifecycle, the Save() and Delete() methods of the NHibernate ISession interface will apply to them, but never to value type instances. To illustrate, lets consider Figure A. Figure A – An order entity with TotalAmount value type TotalAmount is an instance of value type Money. Because value types are completely bound to that their owning entities, TotalAmount is only saved when the Order is saved. Associations and Value Types As we said, not all value types are simple. It’s possible for value types to also define associations. For example, our Money value type could have a property called Currency that is an association to a Currency entity as shown in figure 6.1.2 Figure B – The Money value type with association to a Currency entity. If your value types have associations, they must always point to entities. The reason is that, if those associations could point from entities to value types, a value type could potentially belong to several entities, which isn’t desirable. This is one of the great things about value types; if you update a value type instance, you know that it only affects the entity that owns it. For example, changing the TotalAmount of one Order simply cannot accidentally affect others. So far we’ve talked about value types and entities from an object oriented perspective. To build a more complete picture, we shall now take a look at how the relational model sees value types and entities, and how NHibernate bridges the gap. Bridging from objects to database You may be aware that a database architect would see the world of value types and entities slightly differently to this object oriented view of things. In the database, tables represent the entities, and columns represent the values. Even join tables and lookup tables are entities. So, if all tables represent entities in the database, does that mean we have to map all tables to entities in our .NET domain model? What about those value types we wanted in our model? NHibernate provides constructs for dealing with this. For example, a many-to-many association mapping hides the intermediate association table from the application, so we don’t end up with an unwanted entity in our domain model. Similarly, a collection of value typed strings behaves like a value type from the point of view of the .NET domain model even though it’s mapped to its own table in the database. These features have their uses and can often simplify your C# code. However, over time we have become suspicious of them; these “hidden” entities often end up needing exposure in our applications as business requirements evolve. The many-to-many association table, for example, often has additional columns added as the application matures, so the relationship itself becomes an entity. You might not go far wrong if you make every database-level entity be exposed to the application as an entity class. For example, we’d be inclined to model the many-to-many association as two one-to-many associations to an intervening entity class. We’ll leave the final decision to you, and return to the topic of many-to-many entity associations later in this chapter. Mapping types So far we’ve discussed the differences between value types and entities, as seen from the object oriented and relational database perspectives. We know that mapping entities is quite straight forward – entity classes are simply always mapped to database tables using , , and mapping elements. Value types need something more, which is where mapping types enter the picture. Consider this mapping of the CaveatEmptor User and email address: In ORM, you have to worry about both .NET types and SQL data types. In the example above imagine that the Email field is a .NET string, and EMAIL column is an SQL varchar. We want to tell NHibernate know how to carry out this conversion, which is where NHibernate mapping types come in. In this case, we’ve specified the mapping type "String", which we know is appropriate for this particular conversion. The String mapping type isn’t the only one built into NHibernate; NHibernate comes with various mapping types that define default persistence strategies for primitive .NET types and certain classes, such as like DateTime. Built-in mapping types NHibernate’s built-in mapping types usually reflect the name of the .NET type they map. Sometimes you’ll have a choice of mapping types available to map a particular .NET type to the database. However, the built-in mapping types aren’t designed to perform arbitrary conversions, such as mapping a VARCHAR field value to a .NET Int32 property value. If you want this kind of functionality, you will have to define your own custom value types. We will get to that topic a little later in this chapter. We’ll now discuss the basic types; date and time, objects, large objects, and various other built-in mapping types and show you what .NET and System.Data.DbType data types they handle. DbTypes are used to infer the data provider types (hence SQL data types). .NET primitive mapping types The basic mapping types in table A map .NET primitive types to appropriate DbTypes. Table A Primitive types Mapping Type .NET Type System.Data.DbType Int16 System.Int16 DbType.Int16 Int32 System.Int32 DbType.Int32 Int64 System.Int64 DbType.Int64 Single System.Single DbType.Single Double System.Double DbType.Double Decimal System.Decimal DbType.Decimal Byte System.Byte DbType.Byte Char System.Char DbType.StringFixedLength - 1 character AnsiChar System.Char DbType.AnsiStringFixedLength - 1 character Boolean System.Boolean DbType.Boolean Guid System.Guid DbType.Guid PersistentEnum System.Enum (an enumeration) The DbType for the underlying value TrueFalse System.Boolean DbType.AnsiStringFixedLength - either 'T' or 'F' YesNo System.Boolean DbType.AnsiStringFixedLength - either 'Y' or 'N' You’ve probably noticed that your database doesn’t support some of the DbTypes listed in table A. However, ADO.NET provides a partial abstraction of vendor-specific SQL data types, allowing NHibernate to work with ANSI-standard types when executing data manipulation language (DML). For database-specific DDL generation, NHibernate translates from the ANSI-standard type to an appropriate vendor-specific type, using the built-in support for specific SQL dialects. (You usually don’t have to worry about SQL data types if you’re using NHibernate for data access and data schema definition.) NHibernate supports a number of mapping types coming from Hibernate for compatibility (useful for those coming over from Hibernate or using Hibernate tools to generate hbm.xml files). Table B lists the additional names of NHibernate mapping types. Table B Additional names of NHibernate mapping types Mapping type Additional name Binary binary Boolean boolean Byte byte Character character CultureInfo locale DateTime datetime Decimal big_decimal Double double Guid guid Int16 short Int32 int Int32 integer Int64 long Single float String string TrueFalse true_false Type class YesNo yes_no From this table, you can see that writing type="integer" or type="int" is identical to type="Int32". Note that this table contains many mapping types that will be discussed in the following sections. Date/time mapping types Table C lists NHibernate types associated with dates, times, and timestamps. In your domain model, you may choose to represent date and time data using either System.DateTime or System.TimeSpan. As they have different purposes, the choice should be easy. Table C Date and time typesExcerptOpenSourceSOAch5-6.doc Mapping Type .NET Type System.Data.DbType DateTime System.DateTime DbType.DateTime - ignores the milliseconds Ticks System.DateTime DbType.Int64 TimeSpan System.TimeSpan DbType.Int64 Timestamp System.DateTime DbType.DateTime - as specific as database supports Object mapping types All .NET types in tables A and C are value types (i.e. derived from System.ValueType). This means that they can’t be null; unless you use the .NET 2.0 Nullable structure or the Nullables add-in, as discussed in the next section. Table D lists NHibernate types for handling .NET types derived from System.Object (which can store null values). Table D Nullable object typesExcerptOpenSourceSOAch5-6.doc Mapping Type .NET Type System.Data.DbType String System.String DbType.String AnsiString System.String DbType.AnsiString This table is completed by tables E and F which also contain nullable mapping types. Large object mapping types Table E lists NHibernate types for handling binary data and large objects. Note that none of these types may be used as the type of an identifier property. Table E Binary and large object typesExcerptOpenSourceSOAch5-6.doc Mapping Type .NET Type System.Data.DbType Binary System.Byte[] DbType.Binary BinaryBlob System.Byte[] DbType.Binary StringBlob System.String DbType.String Serializable Any System.Object marked with SerializableAttribute DbType.Binary BinaryBlob and StringClob are mainly supported by SQL Server. They can have a very large size and are fully loaded in memory. This can be a performance killer if used to store very large objects. So use this feature carefully. Note that you must set the NHibernate property "prepare_sql" to "true" to enable this feature. You can find up-to-date design patterns and tips for large object usage on the NHibernate website. Various CLR mapping types Table F lists NHibernate types for various other types of the CLR that may be represented as DbType.Strings in the database. Table F Other CLR-related typesExcerptOpenSourceSOAch5-6.doc Mapping Type .NET Type System.Data.DbType CultureInfo System.Globalization.CultureInfo DbType.String - 5 chars for culture Type System.Type DbType.String holding Assembly Qualified Name Certainly, isn’t the only NHibernate mapping element that has a type attribute. Using mapping types All of the basic mapping types may appear almost anywhere in the NHibernate mapping document, on normal property, identifier property, and other mapping elements. The , , , , , and elements all define an attribute named type. (There are certain limitations on which mapping basic types may function as an identifier or discriminator type, however.) You can see how useful the built-in mapping types are in this mapping for the BillingDetails class: ... The BillingDetails class is mapped as an entity. Its discriminator, id, and Number properties are value typed, and we use the built-in NHibernate mapping types to specify the conversion strategy. It’s often not necessary to explicitly specify a built-in mapping type in the XML mapping document. For instance, if you have a property of .NET type System.String, NHibernate will discover this using reflection and select String by default. We can easily simplify the previous mapping example: .... For each of the built-in mapping types, a constant is defined by the class NHibernate. NHibernateUtil. For example, NHibernate.String represents the String mapping type. These constants are useful for query parameter binding, as discussed in more detail in chapter 8: session.CreateQuery("from Item i where i.Description like :desc") .SetParameter("desc", desc, NHibernate.String) .List(); These constants are also useful for programmatic manipulation of the NHibernate mapping metamodel, as discussed in chapter 3. Of course, NHibernate isn’t limited to the built-in mapping types; you can create your own custom mapping types for handling certain scenarios. We’ll take a look this next, and explain how the mapping type system is a central to NHibernates flexibility. Creating custom mapping types Object-oriented languages like C# make it easy to define new types by writing new classes. Indeed, this is a fundamental part of the definition of object orientation. If you were limited to the predefined built-in NHibernate mapping types when declaring properties of persistent classes, you’d lose much of C#’s expressiveness. Furthermore, your domain model implementation would be tightly coupled to the physical data model, since new type conversions would be impossible. In order to avoid that, NHibernate provides a very powerful feature called custom mapping types. NHibernate provides two user-friendly interfaces that applications may use when defining new mapping types, the first being NHibernate.UserTypes.IUserType. IUserType is suitable for most simple cases and even for some more complex problems. Let’s use it in a simple scenario. Our Bid class defines an Amount property and our Item class defines an InitialPrice property, both monetary values. So far, we’ve only used a simple System.Double to represent the value, mapped with Double to a single DbType.Double column. Suppose we wanted to support multiple currencies in our auction application and that we had to refactor the existing domain model for this change. One way to implement this change would be to add new properties to Bid and Item: AmountCurrency and InitialPriceCurrency. We would then map these new properties to additional VARCHAR columns with the built-in String mapping type. Imagine if we had currency stored in 100 places, this would be lots of changes. We hope you never use this approach! Creating an implementation of IUserType Instead, we should create a MonetaryAmount class that encapsulates both currency and amount. This is a class of the domain model and doesn’t have any dependency on NHibernate interfaces: [Serializable] public class MonetaryAmount { private readonly double value; private readonly string currency; public MonetaryAmount(double value, string currency) { this.value = value; this.currency = currency; } public double Value { get { return value; } } public string Currency { get { return currency; } } public override bool Equals(object obj) { ... } public override int GetHashCode() { ... } } We’ve also made life simpler by making MonetaryAmount an immutable class, meaning it can’t be changed after it’s instantiated. We would have to implement Equals() and GetHashCode() to complete the class - but there is nothing special to consider here aside that they must be consistent, and GetHashCode() should return mostly unique numbers. We will use this new MonetaryAmount to replace the Double, as defined on the InitialPrice property for Item. We would benefit by using this new class in other places, such as the Bid.Amount. The next challenge is in mapping our new MonetaryAmount properties to the database. Suppose we’re working with a legacy database that contains all monetary amounts in USD. Our new class means our application code is no longer restricted to a single currency, but it will take time to get the changes done by the database team. Until this happens, we’d like to store just the Amount property of MonetaryAmount to the database. Because we can’t store the currency yet, we’ll convert all Amounts to USD before we save them, and from USD when we load them. The first step to handling this is to tell NHibernate how to handle our Monetarymount type. To do this, we create a MonetaryAmountUserType class that implements the NHibernate interface IUserType. Our custom mapping type is shown in listing A. Listing A Custom mapping type for monetary amounts in USD using System; using System.Data; using NHibernate.UserTypes; public class MonetaryAmountUserType : IUserType { private static readonly NHibernate.SqlTypes.SqlType[] SQL_TYPES = { NHibernateUtil.Double.SqlType }; public NHibernate.SqlTypes.SqlType[] SqlTypes { |1 get { return SQL_TYPES; } } public Type ReturnedType { get { return typeof(MonetaryAmount); } } |2 public new bool Equals( object x, object y ) { |3 if ( object.ReferenceEquals(x,y) ) return true; if (x == null || y == null) return false; return x.Equals(y); } public object DeepCopy(object value) { return value; } |4 public bool IsMutable { get { return false; } } |5 public object NullSafeGet(IDataReader dr, string[] names, object owner){ |6 object obj = NHibernateUtil.Double.NullSafeGet(dr, names[0]); if ( obj==null ) return null; double valueInUSD = (double) obj; return new MonetaryAmount(valueInUSD, "USD"); } public void NullSafeSet(IDbCommand cmd, object obj, int index) { |7 if (obj == null) { ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value; } else { MonetaryAmount anyCurrency = (MonetaryAmount)obj; MonetaryAmount amountInUSD = MonetaryAmount.Convert( anyCurrency, "USD" ); ((IDataParameter)cmd.Parameters[index]).Value = amountInUSD.Value; } } public static MonetaryAmount Convert( MonetaryAmount m, string targetCurrency) { ... |8 } } The SqlTypes property tells NHibernate what SQL column types to use for DDL schema generation, as seen in #1. The types are subclasses of NHibernate.SqlTypes.SqlType. Notice that this property returns an array of types. An implementation of IUserType may map a single property to multiple columns, but our legacy data model only has a single Double. In #2, we can see that ReturnedType tells NHibernate what .NET type is mapped by this IUserType. The IUserType is responsible for dirty-checking property values (#3). The Equals() method compares the current property value to a previous snapshot and determines whether the property is dirty and must by saved to the database. The IUserType is also partially responsible for creating the snapshot in the first place, as shown in #4. Since MonetaryAmount is an immutable class, the DeepCopy() method returns its argument. In the case of a mutable type, it would need to return a copy of the argument to be used as the snapshot value. This method is also called when an instance of the type is written to or read from the second level cache. NHibernate can make some minor performance optimizations for immutable types. The IsMutable (#5) property tells NHibernate that this type is immutable. The NullSafeGet() method shown near #6 retrieves the property value from the ADO.NET IDataReader. You can also access the owner of the component if you need it for the conversion. All database values are in USD, so you have to convert the MonetaryAmount returned by this method before you show it to the user. In #7, the NullSafeSet() method writes the property value to the ADO.NET IDbCommand. This method takes whatever currency is set and converts it to a simple Double USD value before saving. Note that, for briefness, we haven’t provided a Convert function as shown in #8. If we were to implement it, it would have code that converts between various currencies. Mapping the InitialPrice property of Item can be done as follows: This is the simplest kind of transformation that an implementation of IUserType could perform. It takes a Value Type class and maps it to a single database column. Much more sophisticated things are possible; a custom mapping type could perform validation, it could read and write data to and from an Active Directory, or it could even retrieve persistent objects from a different NHibernate ISession for a different database. You’re limited mainly by your imagination and performance concerns! In a perfect world, we’d prefer to represent both the amount and currency of our monetary amounts in the database, so we’re not limited to storing just USD. We could still use an IUserType for this, but it’s limited; If an IUserType is mapped with more than one property, we can’t use them our HQL or Criteria queries. The NHibernate query engine wouldn’t know anything about the individual properties of MonetaryAmount. You still access the properties in your C# code (MonetaryAmount is just a regular class of the domain model, after all), but not in NHibernate queries. To allow for a custom value type with multiple properties that can be accessed in queries, we should use the ICompositeUserType interface. This interface exposes the properties of our MonetaryAmount to NHibernate. Creating an implementation of ICompositeUserType To demonstrate the flexibility of custom mapping types, we won’t have to change our MonetaryAmount domain model class at all—we change only the custom mapping type, as shown in listing B. Listing B Custom mapping type for monetary amounts in new database schemas using System; using System.Data; using NHibernate.UserTypes; public class MonetaryAmountCompositeUserType : ICompositeUserType { public Type ReturnedClass { get { return typeof(MonetaryAmount); } } public new bool Equals( object x, object y ) { if ( object.ReferenceEquals(x,y) ) return true; if (x == null || y == null) return false; return x.Equals(y); } public object DeepCopy(object value) { return value; } public bool IsMutable { get { return false; } } public object NullSafeGet(IDataReader dr, string[] names, NHibernate.Engine.ISessionImplementor session, object owner) { object obj0 = NHibernateUtil.Double.NullSafeGet(dr, names[0]); object obj1 = NHibernateUtil.String.NullSafeGet(dr, names[1]); if ( obj0==null || obj1==null ) return null; double value = (double) obj0; string currency = (string) obj1; return new MonetaryAmount(value, currency); } public void NullSafeSet(IDbCommand cmd, object obj, int index, NHibernate.Engine.ISessionImplementor session) { if (obj == null) { ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value; ((IDataParameter)cmd.Parameters[index+1]).Value = DBNull.Value; } else { MonetaryAmount amount = (MonetaryAmount)obj; ((IDataParameter)cmd.Parameters[index]).Value = amount.Value; ((IDataParameter)cmd.Parameters[index+1]).Value = amount.Currency; } } public string[] PropertyNames { |1 get { return new string[] { "Value", "Currency" }; } } public NHibernate.Type.IType[] PropertyTypes { |2 get { return new NHibernate.Type.IType[] { NHibernateUtil.Double, NHibernateUtil.String }; } } public object GetPropertyValue(object component, int property) { |3 MonetaryAmount amount = (MonetaryAmount) component; if (property == 0) return amount.Value; else return amount.Currency; } public void SetPropertyValue(object comp, int property, object value) { |4 throw new Exception("Immutable!"); } public object Assemble(object cached, |5 NHibernate.Engine.ISessionImplementor session, object owner) { return cached; } public object Disassemble(object value, |6 NHibernate.Engine.ISessionImplementor session) { return value; } } #1 shows how an implementation of ICompositeUserType has its own properties, defined by PropertyNames. Similarly, the properties each have their own type, as defined by PropertyTypes (#2). The GetPropertyValue() method, shown in #3, returns the value of an individual property of the MonetaryAmount. Since MonetaryAmount is immutable, we can’t set property values individually (see #4) This isn’t a problem because this method is optional anyway. In #5, the Assemble() method is called when an instance of the type is read from the second-level cache. The Disassemble() method is called when an instance of the type is written to the second-level cache, as shown in #6. The order of properties must be the same in the PropertyNames, PropertyTypes, and GetPropertyValues() methods. The InitialPrice property now maps to two columns, so we declare both in the mapping file. The first column stores the value; the second stores the currency of the MonetaryAmount. Note that the order of columns must match the order of properties in your type implementation: In a query, we can now refer to the Amount and Currency properties of the custom type, even though they don’t appear anywhere in the mapping document as individual properties: from Item i where i.InitialPrice.Value > 100.0 and i.InitialPrice.Currency = 'XAF' In this example we’ve expanded the buffer between the .NET object model and the SQL database schema with our custom composite type. Both representations can now handle changes more robustly. If implementing custom types seems complex, relax; you rarely need to use a custom mapping type. An alternative way to represent the MonetaryAmount class is to use a component mapping, as in section 4.4.2, “Using components.” The decision to use a custom mapping type is often a matter of taste. There are few more interfaces that can be used to implement custom types; they are introduced in the next section. Other interfaces to create custom mapping types You may find that the interfaces IUserType and ICompositeUserType do not allow you to easily add more features to your custom types. In this case, you will need to use some of the other interfaces which are in the NHibernate.UserTypes namespace: The IParameterizedType interface allows you to supply parameters to your custom type in the mapping file. This interface has a unique method: SetParameterValues(IDictionary parameters) that will be called at the initialization of your type. Here is an example of mapping providing a parameter: Euro This mapping tells the custom type to use Euro as currency if it isn’t specified. The IEnhancedUserType interface makes it possible to implement a custom type that can be marshalled to and from its string representation. This functionality allows this type to be used as identifier or discriminator type. To create a type that can be used as version, you must implement the IUserVersionType interface. The INullableUserType interface allows you to interpret non-null values in a property as null in the database. When using dynamic-insert or dynamic-update, fields identified as null will not be inserted or updated. This information may also be used when generating the where clause of the SQL command when optimistic locking is enabled. The last interface is different from the previous because it is meant to implement user defined collection types: IUserCollectionType. For more details, take a look at the implementation NHibernate.Test.UserCollection.MyListType in the source code of NHibernate. Now, let’s look at an extremely important application of custom mapping types. Nullable types are found in almost all enterprise applications. Using Nullable types With .NET 1.1, primitive types can not be null; but this is no longer the case in .NET 2.0. Let’s say that we want to add a DismissDate to the class User. As long as a user is active, its DismissDate should be null. But the System.DateTime struct can not be null. And we don’t want to use some "magic" value to represent the null state. With .NET 2.0 (and 3.5 of course), you can simply write: public class User { ... private DateTime? dismissDate; public DateTime? DismissDate { get { return dismissDate; } set { dismissDate = value; } } ... } We omit other properties and methods because we focus on the nullable property. And no change is required in the mapping. If you work with .NET 1.1, the Nullables add-in (in the NHibernateContrib package for versions prior to NHibernate 1.2.0) contains a number of custom mapping types which allow primitive types to be null. For our previous case, we can use the Nullables.NullableDateTime class: using Nullables; [Class] public class User { ... private NullableDateTime dismissDate; [Property] public NullableDateTime DismissDate { get { return dismissDate; } set { dismissDate = value; } } ... } The mapping is quite straightforward: ... It is important to note that, in the mapping, the type of DismissDate must be Nullables.NHibernate.NullableDateTimeType (from the file Nullables.NHibernate.dll). This type is a wrapper used to translate Nullables types from/to database types. But if when using the NHibernate.Mapping.Attributes library, this operation is automatic, that’s why we just had to put the attribute [Property]. The NullableDateTime type behaves exactly like System.DateTime; there are even implicit operators to easily interact with it. The Nullables library contains nullable types for most .NET primitive types supported by NHibernate. You can find more details in NHibernate documentation. Using enumerated types An enumeration (enum) is a special form of value type, which inherits from System.Enum and supplies alternate names for the values of an underlying primitive type. For example, the Comment class defines a Rating. If you recall, in our CaveatEmptor application, users are able to give other comments about other users. Instead of using a simple int property for the rating, we create an enumeration: public enum Rating { Excellent, Ok, Low } We then use this type for the Rating property of our Comment class. In the database, ratings would be represented as the type of the underlying value. In this case (and by default), it is Int32. And that’s all we have to do. We may specify type="Rating" in our mapping, but it is optional; NHibernate can use reflection to find this. One problem you might run into is using enumerations in NHibernate queries. Consider the following query in HQL that retrieves all comments rated “Low”: IQuery q = session.CreateQuery("from Comment c where c.Rating = Rating.Low"); This query doesn’t work, because NHibernate doesn’t know what to do with Rating.Low and will try to use it as a literal. We have to use a bind parameter and set the rating value for the comparison dynamically (which is what we need for other reasons most of the time): IQuery q = session.CreateQuery("from Comment c where c.Rating = :rating"); q.SetParameter("rating", Rating.Low, NHibernateUtil.Enum(typeof(Rating)); The last line in this example uses the static helper method NHibernateUtil.Enum() to define the NHibernate Type, a simple way to tell NHibernate about our enumeration mapping and how to deal with the Rating.Low value. We’ve now discussed all kinds of NHibernate mapping types: built-in mapping types, user-defined custom types, and even components. They’re all considered value types, because they map objects of value type (not entities) to the database. With a good understanding of what value types are, and how they are mapped, you can now move on to the more complex issue of collections of value typed instances.
October 8, 2009
by Alvin Ashcraft
· 69,191 Views · 1 Like
article thumbnail
How to Search for Issues in YouTrack
Now that YouTrack has been announced and adopted by most JetBrains products, it's time to show how it actually works. That's because you report bugs to JetBrains now and then, don't you? Let's start with the way you search for issues. You do that by typing a natural-language-like search query in the search box. For example, the following query finds you all critical issues in project "YouTrack" that should be (or should have been) fixed for version 1.0. Even when you're somewhere outside of the search box, no need to grab your mouse to get there: just press Esc. The primary building block of YouTrack search queries is an attribute-value pair. Issue attributes include issue ID, project, state, type, priority, assignee, reporter, date of creation/update, associated tags etc. For example, to find all critical issues that won't fix in project "IDEA Development", you type the following query: state: {Won't fix} priority: critical project: IDEADEV You can make your query even shorter by skipping unambiguous keywords. For example, in this case, keywords “state”, "priority" and "project" can be safely omitted: #{Won't fix} #critical #IDEADEV On the other hand, "today" would be an ambiguous value because it is valid for two attributes: "updated" and "created". That's why using it without explicitly specifying one of those attributes could render inaccurate search results. Several things make YouTrack query language special, and one of those things is the use of shortcut keywords. When looking for all issues assigned to or reported by yourself, no need to enter a cumbersome query like assigned to: me or reported by: me Instead, type #my Of course, search queries may also contain full-text search items: for example, typing #unresolved light bulbs returns all unresolved issues that contain words "light" and "bulb" in summary, description, comments etc. When you type a query into the search box, YouTrack displays suggestions using query completion: We suggest that you use query completion extensively, for two reasons: Plain and simple: it lets you enter queries faster. More importantly, it automatically inserts special syntax items for you: Colons (:) after attributes. Hash marks (#) before values specified without attributes. Curly braces ({}) around values that contain spaces. In most cases, query completion displays automatically but whenever you need to call it at will, just press Ctrl+Space or Alt+Down. With any character you type, the completion list shrinks to show only the matching options: To help you get the feel of YouTrack search queries, here are some practical examples from our own YouTrack instance: Issues from three IntelliJ IDEA projects assigned to Max Shafirov that were updated this week. Unresolved dotTrace features scheduled for version 4.0. RubyMine issues supporting YAML implemented in version 1.5. Unresolved YouTrack issues sorted by number of votes in descending order. Let's sum it all up. In YouTrack, instead of setting up complicated filters in forms that bolster your inferiority complex, you just type what you are looking for in a manner very similar to how you would say it in plain English, aided by query completion. There have been other issue trackers that used search queries as a filtering option but there are none to my knowledge that rely as heavily on them and make them as usable as YouTrack. For additional information on YouTrack search queries, see the following docs: YouTrack Quick Start Guide: Searching for Issues. YouTrack search demo. YouTrack Search Keyword Reference. YouTrack search features at the JetBrains website. You can download YouTrack 1.0 Beta or use our Early Access Program to receive latest builds. Track with pleasure!
September 24, 2009
by Jura Gorohovsky
· 20,987 Views
article thumbnail
Sorting Collections in Hibernate Using SQL in @OrderBy
When you have collections of associated objects in domain objects, you generally want to specify some kind of default sort order. For example, suppose I have domain objects Timeline and Event: @Entity class Timeline { @Required String description @OneToMany(mappedBy = "timeline") @javax.persistence.OrderBy("startYear, endYear") Set events } @Entity class Event { @Required Integer startYear Integer endYear @Required String description @ManyToOne Timeline timeline } In the above example I've used the standard JPA (Java Persistence API) @OrderBy annotation which allows you to specify the order of a collection of objects via object properties, in this example a @OneToMany association . I'm ordering first by startYear in ascending order and then by endYear, also in ascending order. This is all well and good, but note that I've specified that only the start year is required. (The @Required annotation is a custom Hibernate Validator annotation which does exactly what you would expect.) How are the events ordered when you have several events that start in the same year but some of them have no end year? The answer is that it depends on how your database sorts null values by default. Under Oracle 10g nulls will come last. For example if two events both start in 2001 and one of them has no end year, here is how they are ordered: 2001 2002 Some event 2001 2003 Other event 2001 Event with no end year What if you want to control how null values are ordered so they come first rather than last? In Hibernate there are several ways you could do this. First, you could use the Hibernate-specific @Sort annotation to perform in-memory (i.e. not in the database) sorting, using natural sorting or sorting using a Comparator you supply. For example, assume I have an EventComparator helper class that implements Comparator. I could change Timeline's collection of events to look like this: @OneToMany(mappedBy = "timeline") @org.hibernate.annotations.Sort(type = SortType.COMPARATOR, comparator = EventCompator) Set events Using @Sort will perform sorting in-memory once the collection has been retrieved from the database. While you can certainly do this and implement arbitrarily complex sorting logic, it's probably better to sort in the database when you can. So we now need to turn to Hibernate's @OrderBy annotation, which lets you specify a SQL fragment describing how to perform the sort. For example, you can change the events mapping to : @OneToMany(mappedBy = "timeline") @org.hibernate.annotations.OrderBy("start_year, end_year") Set events This sort order is the same as using the JPA @OrderBy with "startYear, endYear" sort order. But since you write actual SQL in Hibernate's @OrderBy you can take advantage of whatever features your database has, at the possible expense of portability across databases. As an example, Oracle 10g supports using a syntax like "order by start_year, end_year nulls first" to order null end years before non-null end years. You could also say "order by start_year, end year nulls last" which sorts null end years last as you would expect. This syntax is probably not portable, so another trick you can use is the NVL function, which is supported in a bunch of databases. You can rewrite Timeline's collection of events like so: @OneToMany(mappedBy = "timeline") @org.hibernate.annotations.OrderBy("start_year, nvl(end_year , start_year)") Set events The expression "nvl(end_year , start_year)" simply says to use end_year as the sort value if it is not null, and start_year if it is null. So for sorting purposes you end up treating end_year as the same as the start_year if end_year is null. In the contrived example earlier, applying the nvl-based sort using Hibernate's @OrderBy to specify SQL sorting criteria, you now end with the events sorted like this: 2001 Event with no end year 2001 2002 Some event 2001 2003 Other event Which is what you wanted in the first place. So if you need more complex sorting logic than what you can get out of the standard JPA @javax.persistence.OrderBy, try one of the Hibernate sorting options, either @org.hibernate.annotations.Sort or @org.hibernate.annotations.OrderBy. Adding a SQL fragment into your domain class isn't necessarily the most elegant thing in the world, but it might be the most pragmatic thing.
September 16, 2009
by Scott Leberknight
· 102,225 Views
article thumbnail
Calcular A Idade Em SQL
Faz o cálculo da idade de uma pessoa utilizando sql oracle Select Trunc ( (SYSDATE - to_date('14/07/1980','dd/mm/yyyy')) /365, 0 ) as "age" from Dual
September 13, 2009
by Erico Marineli
· 6,287 Views
article thumbnail
JPA Implementation Patterns: Field Access vs. Property Access
i will continue the jpa implementation patterns series by discussing the relative merits of field access vs. property access. the jpa specification allows two ways for the persistence provider to access the persistent state of an entity. the persistence provider can either invoke javabeans style property accessors (getters and setters) or access the instance fields of the entity directly. which method is used depends on whether you have annotated the properties or the fields of an entity. the jpa 1.0 specification does not allow you to mix access types within an entity or even an entity hierarchy. if you have annotated both fields and properties, the behaviour is undefined. the jpa 2.0 specification has the @access annotation that makes it possible mix access types within an entity or entity hierarchy. but the interesting question remains; which access type to use? a question that has been discussed before , but one i couldn't resist commenting on too. encapsulation - property access is said to provide better encapsulation, because directly accessing fields is bad, right? well actually, using property access obliges you to write getters and setters for all your persistent properties. these methods not only allow the jpa provider to set the fields, they also allow any other user of your entity class to do this! using field access allows you to write only the getters and setters you want to ( they're evil , remember?) and also write them as you want them, for example by doing validation in your setters or some calculation in your getters. in contrast, making these methods smarter when using property access is just asking for trouble . performance - some people prefer field access because it supposedly offers better performance than property access. but that is a very bad reason to choose field access. modern optimizing jvms will make property access perform just as fast as field access and in any case database calls are orders of magnitude slower than either field access or method invocations. lazy loading in hibernate - hibernate's lazy loading implementation always initializes a lazy proxy when any method on that proxy is invoked. the only exception to this is the method annotated with the @id annotation when you use property access. but when you use field access there is no such method and hibernate initializes the proxy even when invoking the method that returns the identity of the entity. while some propose to use property access until this bug is fixed, i am not in favour of basing design decisions on framework bugs. if this bug really hurts your performance you might want to try and get the id of entity with the following code: serializable id = ((hibernateproxy) entity).gethibernatelazyinitializer().getidentifier() it's nasty, but at least this code will be localized to where you really need it. field access in hibernate - it is good to know that while field access is ok for hibernate to populate your entities, your code should still access those values through methods. otherwise you will fall into the first of the hibernate proxy pitfalls mentioned by my colleague maarten winkels. to summarize i think field access is the way to go because it offers better encapsulation (without it properly managing bidirectional associations is impossible) and the performance impact is negligible (#1 on the performance problems top 10 is still the interplay between the database and your java app). the only downside are some snafu's in hibernate's lazy loading implementation that require you to take extra care when using field access. what access type do you prefer? do you see any difference in the way field access and property access are implemented in jpa providers other than hibernate? please let me know by leaving a comment below. see you at the next jpa implementation patterns blog in which i will talk about mapping inheritance hierarchies in jpa. from http://blog.xebia.com
September 9, 2009
by Vincent Partington
· 54,275 Views · 2 Likes
article thumbnail
Application Logging: What, When, How
logging is a fundamental part of applications. every application has a varying flavor of logging mechanism. a well designed logging system is a huge utility for system administrators and developers, especially the support team. logs save many valuable hours for both the support team or developers. as users execute programs at the front end, the system invisibly builds a vault of event information (log entries) for system administrators and the support team. after stating its value, let’s try to figure out the logging requirements for an application. java has a standard logging api in its new versions (java.util.logging). log4j is also a well-known library for logging. we implemented a transparent “logging service” in our application framework. you may prefer some kind of logging implementations but there are some other important questions you have to answer in your application design which are what to log, when to log, how much to log, how to control logging and how correlate it with your exception system. what to log some application exceptions should be logged: why not log all exceptions? some exceptions are managed exceptions which are thrown by application as a warning or as a validation error to the user. if all validation errors or application exceptions are included in logs, the logs will lose their usefulness. it would contain many entries, it makes it hard to reach valuable entries. here, we should discriminate exceptions if they should be logged. we used a loggable mark interface to determine if it is included in logs. another best practice is to have a single global exception handler. in this way, application developers don’t worry about logging of any exception they generate. a single exception handler means a single unified and neat exception logging mechanism. some application events should be logged: for major components of an application we may log lifecycle events like start, stop and restart. some security-related events may be logged such as unauthorized url access attempts, user logins etc. some resource thresholds may be exceeded and should also be logged. some application states should be logged: in some codes, we should ask that “what could go wrong here in this code”. if this state occurs, we may throw an exception or log it (if we don’t want to interrupt current process) with some levels like error, warning or information. for example if a connection is normally released while it is uncommitted, that info may be logged as uncommitted connection release that points some application code problems. some debug information may be logged: in some applications, you may have some errors and can’t find why this is happening. you may add some debug logs into your code and redeploy it to diagnose the problem. some chronic bugs deserve debug traces which can’t be detected in development environment. executed sqls may be logged: in some conditions, we may want to get the sql statement executed by an application. we should easily switch logging on without start/stop of system. let’s say user complain about wrong report result when executing a report. if we don’t have a clue about that we may log sql and trace it. user http requests may be logged: we may need what is coming from the user with full parameter details. to achieve this kind of logging we have to plug a log service in servlets and jsp pages. executing threads may be logged: i mentioned a blackbox implementation in our applications in one of my previous posts. you may log executing thread information to that black box to figure out what may go wrong in a system crash. javascript errors may be logged: this may be considered same with first item but its implementations totally differs. you need to have a global javascript exception handler. in the handler, you submit javascript error with ajax to log on the server (assuming it is not an ajax error). some best practices as i said above, the exception handling system is an important plug point for logging. in all our servlets and jsps, the main code blocks have the following structure to enable global exception handling. this standard eliminates the work of logging exceptions by developers (transparent unified logging): try { } catch(exception e) { globalhandler.handleexception(e); } we named “log medium” to mean where to store log entries but in java logging api it is called handlers. for some type of logs, database logs are handy since you can run powerful sql queries against log table which is merely possible in files. to assign log messages to the appropriate log levels is also important. otherwise some wrong alerts would mislead system administrators. we used system.err stream for application-level logging which is same place with e.printstacktrace() which may be printed with our global handler log entry at the same time. we wouldn’t need all exception’s stack trace but some may be very useful to see where the root of the problem (i.e. stackoverflowexception). when logging exceptions we used following format. some articles recommends that we’d better to include problem failover suggestion but i think this information should be given to the user not included in the logs. logs are rarely read but exceptions are in front of users. log entry should answer following questions: who (username) , when (timestamp) , where (context, servletorpage,database) , what (command) , result (exception) [errorhandlername] username: userabc databasename: abc timestamp: 15.07.2009 13:02:08 context:servlet page: /prod/sales/salesorders.jsp window: windwname command: savesalesorder exception: shortdescriptionofexception exceptionstacktracehere in a clustered environment, logging should be considered. we separated same type of log files with a cluster node name suffix to the file name. otherwise, concurrent log writes may lead to some problems. system_node01.log system_node02.log as a last item, logging may be a very interesting performance killer. if applications begin to log a lot, application performance may severely fall down. i have a real life story for that. once we had forgotten to include an image file in deployment package. it was being used in every page. when we started system after installment, page response was so slow. log files seem small enough that may not incur problem. after, opening and reading log files, we realized that log frequency (stating image is missing) was high and that was causing the problem. in conclusion, your log file size and log writing frequency should be small.
September 1, 2009
by Adam Brown
· 79,460 Views · 2 Likes
article thumbnail
JPA Performance, Don't Ignore the Database
Good Database schema design is important for performance. One of the most basic optimizations is to design your tables to take as little space on the disk as possible , this makes disk reads faster and uses less memory for query processing. Data Types You should use the smallest data types possible, especially for indexed fields. The smaller your data types, the more indexes (and data) can fit into a block of memory, the faster your queries will be. Normalization Database Normalization eliminates redundant data, which usually makes updates faster since there is less data to change. However a Normalized schema causes joins for queries, which makes queries slower, denormalization speeds retrieval. More normalized schemas are better for applications involving many transactions, less normalized are better for reporting types of applications. You should normalize your schema first, then de-normalize later. Applications often need to mix the approaches, for example use a partially normalized schema, and duplicate, or cache, selected columns from one table in another table. With JPA O/R mapping you can use the @Embedded annotation for denormalized columns to specify a persistent field whose @Embeddable type can be stored as an intrinsic part of the owning entity and share the identity of the entity. Database Normalization and Mapping Inheritance Hiearchies The Class Inheritance hierarchy shown below will be used as an example of JPA O/R mapping. In the Single table per class mapping shown below, all classes in the hierarchy are mapped to a single table in the database. This table has a discriminator column (mapped by @DiscriminatorColumn), which identifies the subclass. Advantages: This is fast for querying, no joins are required. Disadvantages: wastage of space since all inherited fields are in every row, a deep inheritance hierarchy will result in wide tables with many, some empty columns. In the Joined Subclass mapping shown below, the root of the class hierarchy is represented by a single table, and each subclass has a separate table that only contains those fields specific to that subclass. This is normalized (eliminates redundant data) which is better for storage and updates. However queries cause joins which makes queries slower especially for deep hierachies, polymorphic queries and relationships. In the Table per Class mapping (in JPA 2.0, optional in JPA 1.0), every concrete class is mapped to a table in the database and all the inherited state is repeated in that table. This is not normlalized, inherited data is repeated which wastes space. Queries for Entities of the same type are fast, however polymorphic queries cause unions which are slower. Know what SQL is executed You need to understand the SQL queries your application makes and evaluate their performance. Its a good idea to enable SQL logging, then go through a use case scenario to check the executed SQL. Logging is not part of the JPA specification, With EclipseLink you can enable logging of SQL by setting the following property in the persistence.xml file: With Hibernate you set the following property in the persistence.xml file: Basically you want to make your queries access less data, is your application retrieving more data than it needs, are queries accessing too many rows or columns? Is the database query analyzing more rows than it needs? Watch out for the following: queries which execute too often to retrieve needed data retrieving more data than needed queries which are too slow you can use EXPLAIN to see where you should add indexes With MySQL you can use the slow query log to see which queries are executing slowly, or you can use the MySQL query analyzer to see slow queries, query execution counts, and results of EXPLAIN statements. Understanding EXPLAIN For slow queries, you can precede a SELECT statement with the keyword EXPLAIN to get information about the query execution plan, which explains how it would process the SELECT, including information about how tables are joined and in which order. This helps find missing indexes early in the development process. You should index columns that are frequently used in Query WHERE, GROUP BY clauses, and columns frequently used in joins, but be aware that indexes can slow down inserts and updates. Lazy Loading and JPA With JPA many-to-one and many-to-many relationships lazy load by default, meaning they will be loaded when the entity in the relationship is accessed. Lazy loading is usually good, but if you need to access all of the "many" objects in a relationship, it will cause n+1 selects where n is the number of "many" objects. You can change the relationship to be loaded eagerly as follows : However you should be careful with eager loading which could cause SELECT statements that fetch too much data. It can cause a Cartesian product if you eagerly load entities with several related collections. If you want to override the LAZY fetch type for specific use cases, you can use Fetch Join. For example this query would eagerly load the employee addresses: In General you should lazily load relationships, test your use case scenarios, check the SQL log, and use @NameQueries with JOIN FETCH to eagerly load when needed. Partitioning The main goal of partitioning is to reduce the amount of data read for particular SQL operations so that the overall response time is reduced Vertical Partitioning splits tables with many columns into multiple tables with fewer columns, so that only certain columns are included in a particular dataset, with each partition including all rows. Horizontal Partitioning segments table rows so that distinct groups of physical row-based datasets are formed. All columns defined to a table are found in each set of partitions. An example of horizontal partitioning might be a table that contains historical data being partitioned by date. Vertical Partitioning In the example of vertical partitioning below a table that contains a number of very wide text or BLOB columns that aren't referenced often is split into two tables with the most referenced columns in one table and the seldom-referenced text or BLOB columns in another. By removing the large data columns from the table, you get a faster query response time for the more frequently accessed Customer data. Wide tables can slow down queries, so you should always ensure that all columns defined to a table are actually needed. The example below shows the JPA mapping for the tables above. The Customer data table with the more frequently accessed and smaller data types is mapped to the Customer Entity, the CustomerInfo table with the less frequently accessed and larger data types is mapped to the CustomerInfo Entity with a lazily loaded one to one relationship to the Customer. Horizontal Partitioning The major forms of horizontal partitioning are by Range, Hash, Hash Key, List, and Composite. Horizontal partitioning can make queries faster because the query optimizer knows what partitions contain the data that will satisfy a particular query and will access only those necessary partitions during query execution. Horizontal Partitioning works best for large database Applications that contain a lot of query activity that targets specific ranges of database tables. Hibernate Shards Partitioning data horizontally into "Shards" is used by google, linkedin, and others to give extreme scalability for very large amounts of data. eBay "shards" data horizontally along its primary access path. Hibernate Shards is a framework that is designed to encapsulate support for horizontal partitioning into the Hibernate Core. Caching JPA Level 2 caching avoids database access for already loaded entities, this makes reading frequently accessed unmodified entities faster, however it can give bad scalability for frequent or concurrently updated entities. You should configure L2 caching for entities that are: read often modified infrequently Not critical if stale You should also configure L2 (vendor specific) caching for maxElements, time to expire, refresh... References and More Information: JPA Best Practices presentation MySQL for Developers Article MySQL for developers presentation MySQL for developers screencast Keeping a Relational Perspective for Optimizing Java Persistence Java Persistence with Hibernate Pro EJB 3: Java Persistence API Java Persistence API 2.0: What's New ? High Performance MySQL book Pro MySQL, Chapter 6: Benchmarking and Profiling EJB 3 in Action sharding the hibernate way JPA Caching Best Practices for Large-Scale Web Sites: Lessons from eBay
August 31, 2009
by Carol McDonald
· 41,762 Views · 1 Like
article thumbnail
JPA Caching
JPA has 2 levels of caching. The first level of caching is the persistence context. The JPA Entity Manager maintains a set of Managed Entities in the Persistence Context. The Entity Manager guarantees that within a single Persistence Context, for any particular database row, there will be only one object instance. However the same entity could be managed in another User's transaction, so you should use either optimistic or pessimistic locking as explained in JPA 2.0 Concurrency and locking The code below shows that a find on a managed entity with the same id and class as another in the same persistence context , will return the same instance. @Stateless public ShoppingCartBean implements ShoppingCart { @PersistenceContext EntityManager entityManager; public OrderLine createOrderLine(Product product,Order order) { OrderLine orderLine = new OrderLine(order, product); entityManager.persist(orderLine); //Managed OrderLine orderLine2 =entityManager.find(OrderLine, orderLine.getId())); (orderLine == orderLine2) // TRUE return (orderLine); } } The diagram below shows the life cycle of an Entity in relation to the Persistent Context. The code below illustrates the life cycle of an Entity. A reference to a container managed EntityManager is injected using the persistence context annotation. A new order entity is created and the entity has the state of new. Persist is called, making this a managed entity. because it is a stateless session bean it is by default using container managed transactions , when this transaction commits , the order is made persistent in the database. When the orderline entity is returned at the end of the transaction it is a detached entity. The Persistence Context can be either Transaction Scoped-- the Persistence Context 'lives' for the length of the transaction, or Extended-- the Persistence Context spans multiple transactions. With a Transaction scoped Persistence Context, Entities are "Detached" at the end of a transaction. As shown below, to persist the changes on a detached entity, you call the EntityManager's merge() operation, which returns an updated managed entity, the entity updates will be persisted to the database at the end of the transaction. An Extended Persistence Context spans multiple transactions, and the set of Entities in the Persistence Context stay Managed. This can be useful in a work flow scenario where a "conversation" with a user spans multiple requests. The code below shows an example of a Stateful Session EJB with an Extended Persistence Context in a use case scenario to add line Items to an Order. After the Order is persisted in the createOrder method, it remains managed until the EJB remove method is called. In the addLineItem method , the Order Entity can be updated because it is managed, and the updates will be persisted at the end of the transaction. The example below contrasts updating the Order using a transaction scoped Persistence Context verses an extended Persistence context. With the transaction scoped persistence context, an Entity Manager find must be done to look up the Order, this returns a Managed Entity which can be updated. With the Extended Persistence Context the find is not necessary. The performance advantage of not doing a database read to look up the Entity, must be weighed against the disadvantages of memory consumption for caching, and the risk of cached entities being updated by another transaction. Depending on the application and the risk of contention among concurrent transactions this may or may not give better performance / scalability. JPA second level (L2) caching JPA second level (L2) caching shares entity state across various persistence contexts. JPA 1.0 did not specify support of a second level cache, however, most of the persistence providers provided support for second level cache(s). JPA 2.0 specifies support for basic cache operations with the new Cache API, which is accessible from the EntityManagerFactory, shown below: If L2 caching is enabled, entities not found in persistence context, will be loaded from L2 cache, if found. The advantages of L2 caching are: avoids database access for already loaded entities faster for reading frequently accessed unmodified entities The disadvantages of L2 caching are: memory consumption for large amount of objects Stale data for updated objects Concurrency for write (optimistic lock exception, or pessimistic lock) Bad scalability for frequent or concurrently updated entities You should configure L2 caching for entities that are: read often modified infrequently Not critical if stale You should protect any data that can be concurrently modified with a locking strategy: Must handle optimistic lock failures on flush/commit configure expiration, refresh policy to minimize lock failures The Query cache is useful for queries that are run frequently with the same parameters, for not modified tables. The EclipseLink JPA persistence provider caching Architecture The EclipseLink caching Architecture is shown below. Support for second level cache in EclipseLink is turned on by default, entities read are L2 cached. You can disable the L2 cache. EclipseLink caches entities in L2, Hibernate caches entity id and state in L2. You can configure caching by Entity type or Persistence Unit with the following configuration parameters: Cache isolation, type, size, expiration, coordination, invalidation,refreshing Coordination (cluster-messaging) Messaging: JMS, RMI, RMI-IIOP, … Mode: SYNC, SYNC+NEW, INVALIDATE, NONE The example below shows configuring the L2 cache for an entity using the @Cache annotation The Hibernate JPA persistence provider caching Architecture The Hibernate JPA persistence provider caching architecture is different than EclipseLink: it is not configured by default, it does not cache enities just id and state, and you can plug in different L2 caches. The diagram below shows the different L2 cache types that you can plug into Hibernate. The configuration of the cache depends on the type of caching plugged in. The example below shows configuring the hibernate L2 cache for an entity using the @Cache annotation For More Information: Introducing EclipseLink EclipseLink JPA User Guide Hibernate Second Level Cache Speed Up Your Hibernate Applications with Second-Level Caching Hibernate caching Java Persistence API 2.0: What's New ? Beginning Java™ EE 6 Platform with GlassFish™ 3 Pro EJB 3: Java Persistence API (JPA 1.0)
August 24, 2009
by Carol McDonald
· 80,845 Views · 39 Likes
article thumbnail
JPA Implementation Patterns: Lazy Loading
Model your complete database with all its relations with this JPA pattern for lazy loading.
August 19, 2009
by Vincent Partington
· 120,443 Views · 6 Likes
article thumbnail
Urlencode/urldecode As MySQL Stored Functions
DELIMITER ; DROP FUNCTION IF EXISTS multiurldecode; DELIMITER | CREATE FUNCTION multiurldecode (s VARCHAR(4096)) RETURNS VARCHAR(4096) DETERMINISTIC CONTAINS SQL BEGIN DECLARE pr VARCHAR(4096) DEFAULT ''; IF ISNULL(s) THEN RETURN NULL; END IF; REPEAT SET pr = s; SELECT urldecode(s) INTO s; UNTIL pr = s END REPEAT; RETURN s; END; | DELIMITER ;
August 18, 2009
by Snippets Manager
· 13,676 Views · 5 Likes
article thumbnail
Using SelfPopulatingCache in Ehcache
Often you will notice that Ehcache is used mostly like a tool that implements highly configurable maps. Sometimes developers configure time-to-live properties, or make use of disk-store functionality, but you can rarely meet someone who has cache population/eviction process that makes sense. In the perfect world I would expect cache to be a universal pool. I request a value for a key and would like to get it whenever it is possible and as fast as possible with just one line of code. But in reality I usually can see huge cache population code on the application startup, daemon threads that update caches in eternal loop and numerous “ifs” around cache.get() calls. In my strive to the perfect world I’ve discovered a SelfPopulatingCache class in Ehcache. In this article I will describe how using SelfPopulatingCache class one can implement a cache with self creating objects with optional auto-updating. In some way this example is an implementation of ideas mentioned in Ehcache documentation. Example What you will see down here: A Reader that fetches an object from cache 5 times every 0.5 seconds. Behind scenes cache will create a new object if there is no such object is there in cache for a key requested. A daemon thread will trigger cache refresh every 2 seconds. The most important class in this example is ExampleCacheProvider. package com.blogspot.mikler.java; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; import net.sf.ehcache.constructs.blocking.SelfPopulatingCache; import net.sf.ehcache.constructs.blocking.CacheEntryFactory; public class ExampleCacheProvider { private CacheManager cacheManager; private CacheEntryFactory updatingFactory; public SelfPopulatingCache selfPopulatingCache; public ExampleCacheProvider() throws Exception { cacheManager = CacheManager.create(); Ehcache originalCache = cacheManager.getCache("com.blogspot.mikler.java.cache"); final String cacheType = System.getProperty("com.blogspot.mikler.java.cache.factory"); if (cacheType == null || cacheType.equals("create")){ updatingFactory = new ExampleCacheEntryFactory(); } else { updatingFactory = new ExampleUpdatingCacheEntryFactory(); } selfPopulatingCache = new SelfPopulatingCache(originalCache, updatingFactory); //chache refresh thread Thread updatingThread = new Thread(){ public void run() { while (true){ System.out.println("!!!!! Doing refresh !!!!!"); selfPopulatingCache.refresh(); try { Thread.sleep(2000); } catch (InterruptedException e) { System.out.println("Interrupted"); } } } }; updatingThread.setDaemon(true); updatingThread.start(); } public Ehcache getCache(){ return selfPopulatingCache; } } What it does is creating simple Ehcache (original cache) and wrapping it with SelfPopulatingCache (selfPopulatingCache). We can use this class the same way as CacheManager, so one can consider extending CacheManager, but to keep it simple here we'll stick to this kind of cache source. While wrapping we specify updatingFactory, which can be set to one of two options: ExampleCacheEntryFactory (line 19) and ExampleUpdatingCacheEntryFactory(line 21). For the purposes of this example the choice between this two options is done based on the “com.blogspot.mikler.java.cache.factory” system property value. The difference between this two is that ExampleCacheEntryFactory implements CacheEntryFactory interface, while ExampleUpdatingCacheEntryFactory extends ExampleCacheEntryFactory and implements UpdatingCacheEntryFactory. The difference between using each of this options is explained later on. Meanwhile here is the code of both classes. package com.blogspot.mikler.java; import net.sf.ehcache.constructs.blocking.CacheEntryFactory; public class ExampleCacheEntryFactory implements CacheEntryFactory { public Object createEntry(Object key) throws Exception { System.out.println("++++++creating entry for key = " + key); return new StringBuffer(Long.toString(Math.round(100*Math.random())) + key+"0"); } } package com.blogspot.mikler.java; import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory; public class ExampleUpdatingCacheEntryFactory extends ExampleCacheEntryFactory implements UpdatingCacheEntryFactory { public void updateEntryValue(Object key, Object value) throws Exception { System.out.println("~~~~~~UPDATING entry for key = " + key); final StringBuffer stringBuffer = (StringBuffer) value; stringBuffer.append(stringBuffer.length()); } } As you can see in this example as cache element’s key string used, while StringBuffer is used as a value. In createEntry() method in ExampleCacheEntryFactory StringBuffer is created with leading random number. While in updateEntryValue() method of ExampleUpdatingCacheEntryFactory existing StringBuffer length is appended to the buffer itself. And finally, here goes our Reader main class. It fetches our wrapped cache, get’s value for “foo” key from it and stores it into final local variable fooOriginalBuffer, that is never changed late in Reader’s code. Then it starts doing 5 iterations of getting value for “foo” key from cache, displaying debug info and stats, and sleeping for one second. The code is simple as this. package com.blogspot.mikler.java; import net.sf.ehcache.Ehcache; public class Reader { private ExampleCacheProvider exampleCacheProvider; public Reader(ExampleCacheProvider exampleCacheProvider) { this.exampleCacheProvider = exampleCacheProvider; } public void run(){ Ehcache cache = exampleCacheProvider.getCache(); final StringBuffer fooOriginalBuffer = (StringBuffer) cache.get("foo").getValue(); for (int i = 0; i < 5; i++){ System.out.println("----------------------------------"); System.out.println("Starting iteration " + i); StringBuffer fooBuffer = (StringBuffer) cache.get("foo").getValue(); System.out.println("fooBuffer. = " + fooBuffer.toString()); System.out.println("fooOriginalBuffer = " + fooOriginalBuffer.toString()); System.out.println("cache.getSize() = " + cache.getSize()); System.out.println("----------------------------------"); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Interrupted"); } } } public static void main(String[] args) throws Exception { ExampleCacheProvider cacheProvider = new ExampleCacheProvider(); Reader reader = new Reader(cacheProvider); reader.run(); } } Let’s run it with both updatingFactory options. Output of running the Reader with ExampleCacheEntryFactory (-Dcom.blogspot.mikler.java.cache.factory=create) !!!!! Doing refresh !!!!! ++++++creating entry for key = foo ---------------------------------- Starting iteration 0 fooBuffer. = 35foo0 fooOriginalBuffer = 35foo0 cache.getSize() = 1 ---------------------------------- ---------------------------------- Starting iteration 1 fooBuffer. = 35foo0 fooOriginalBuffer = 35foo0 cache.getSize() = 1 ---------------------------------- !!!!! Doing refresh !!!!! ++++++creating entry for key = foo ---------------------------------- Starting iteration 2 fooBuffer. = 36foo0 fooOriginalBuffer = 35foo0 cache.getSize() = 1 ---------------------------------- ---------------------------------- Starting iteration 3 fooBuffer. = 36foo0 fooOriginalBuffer = 35foo0 cache.getSize() = 1 ---------------------------------- !!!!! Doing refresh !!!!! ++++++creating entry for key = foo ---------------------------------- Starting iteration 4 fooBuffer. = 51foo0 fooOriginalBuffer = 35foo0 cache.getSize() = 1 ---------------------------------- And here how the output looks like while running Reader with ExampleUpdatingCacheEntryFactory as updatingFactory (-Dcom.blogspot.mikler.java.cache.factory=update) !!!!! Doing refresh !!!!! ++++++creating entry for key = foo ---------------------------------- Starting iteration 0 fooBuffer. = 19foo0 fooOriginalBuffer = 19foo0 cache.getSize() = 1 ---------------------------------- ---------------------------------- Starting iteration 1 fooBuffer. = 19foo0 fooOriginalBuffer = 19foo0 cache.getSize() = 1 ---------------------------------- !!!!! Doing refresh !!!!! ~~~~~~UPDATING entry for key = foo ---------------------------------- Starting iteration 2 fooBuffer. = 19foo06 fooOriginalBuffer = 19foo06 cache.getSize() = 1 ---------------------------------- ---------------------------------- Starting iteration 3 fooBuffer. = 19foo06 fooOriginalBuffer = 19foo06 cache.getSize() = 1 ---------------------------------- !!!!! Doing refresh !!!!! ~~~~~~UPDATING entry for key = foo ---------------------------------- Starting iteration 4 fooBuffer. = 19foo067 fooOriginalBuffer = 19foo067 cache.getSize() = 1 ---------------------------------- Conclusion As you can see the output is quite different and here are some conclusions we come to from analyzing it: No NullPointerException is occurs while trying to get object from cache that is not there. It is being created in both cases. If updatingFactory is instance of CacheEntryFactory (ExampleCacheEntryFactory in our case) when cache.refresh() is called each object in cache is being recreated. Also when updatingFactory is instance of CacheEntryFactory final fooOriginalBuffer variable is not updated. Meanwhile in case when updatingFactory is instance of CacheEntryFactory (UpdatingCacheEntryFactory in our case) when cache.refresh() is called each object in cache gets updated instead of being recreated. And final fooOriginalBuffer variable value is updated as well. (Actually this variable itself is passed to updateEntryValue() method of ExampleUpdatingCacheEntryFactory) Instructions about how to check out the source code for this article you can find in the original post. Originally posted on miklerjava.blogspot.com
August 17, 2009
by Mikhail Kolesnik
· 29,802 Views
article thumbnail
EAN13 Check With SQL
SELECT attributes_ean FROM products_attributes WHERE LENGTH(attributes_ean) = 13 AND SUBSTRING((10 - (((( SUBSTRING(attributes_ean FROM 2 FOR 1) + SUBSTRING(attributes_ean FROM 4 FOR 1) + SUBSTRING(attributes_ean FROM 6 FOR 1) + SUBSTRING(attributes_ean FROM 8 FOR 1) + SUBSTRING(attributes_ean FROM 10 FOR 1) + SUBSTRING(attributes_ean FROM 12 FOR 1) )*3) + ( SUBSTRING(attributes_ean FROM 1 FOR 1) + SUBSTRING(attributes_ean FROM 3 FOR 1) + SUBSTRING(attributes_ean FROM 5 FOR 1) + SUBSTRING(attributes_ean FROM 7 FOR 1) + SUBSTRING(attributes_ean FROM 9 FOR 1) + SUBSTRING(attributes_ean FROM 11 FOR 1) )) MOD 10)) FROM -1 FOR 1) != SUBSTRING(attributes_ean FROM 13 FOR 1)
August 5, 2009
by Snippets Manager
· 1,386 Views
article thumbnail
Don't Break the Optimistic Locking
During Jazoon 2009 I got a few minutes of private attention from Mike Keith to my last article about domain models. That small time was worthy the whole conference for me since Mike pointed the gaps in my text as well as some valuable hints on how to better translate domain models in JPA annotations. From that short conversation, a special sentence remains alive in my memory: don't break the optimistic locking. After a review on my original code I agreed with Mike that I was ignoring the optimistic locking in my service layer - a common mistake noticed over the Internet and also in conversation with other friends. The problem is not new and the solution is neither new, but I decided to blog it shortly to my personal reference and eventually for your help. The problem: breaking the optimistic locking. When exposing domain models through web-services you should serialize your entities between the client and the service, and every time you do that you have a detached JPA entity. In order to persist the detached objects in the database you need to re-attach them in to a new persistence context - and that's where the problem begins. Concurrent threads can access the same write method, reading a same entity, modifying it and then writing back the detached entity in the database. In my original code I was reading the latest version of the entity and then copying the field values from the external entity to the latest one. In this way I guaranteed the unbreakable writing code but I felt in the most basic mistake of JPA: I broken the consistency of the entities. From the Mike book: it is just an accident waiting to happen. Below you find the trap example from my original code: @Override public FpUser update(FpUser entity) throws Exception { FpUser attached = manager.find(FpUser.class, entity.getId()); // Here I am modifying the latest entity and not the detached one. attached.setEmail(entity.getEmail()); attached.setName(entity.getName()); return manager.merge(attached); } From the code above, we can enumerate the steps required to bypass the optimistic locking: Client A reads entity.v1 Client B reads entity.v1 Client A modifies the entity.version1 and starts an update.transaction#1 Client B modifies the entity.version1 and starts an update.transaction#2 update.transaction#1 updates the fields received from Client A, merge the entity - that receives the version v2 - but get suspended before to finish. update.transaction#2 updates the fields and received from Client B, updates the version to v3 and finishes returning the entity.v3 to the Client B. update.transaction#1 finishes returning the entity.v2 to the Client A. At the end of the above execution, we have the following scenario: Client A has an instance of the entity version 2 Client B has an instance of the entity version 3 (it actually jumped directly from version 1 to 3, without even noticing the changes of the version 2) The database has the data from version 3 The worse side effect of this trap is that Client A believes the current data persisted in the database is the ones from version 2, but actually it is wrong since the version 3 is currently stored in the database. The inconsistency could be easily detected by the optimistic locking of JPA, but since I am reading the latest version on every update operation the code won't throw the proper exception and the clients will become inconsistent with the server side. Solution: keep it simple The default mechanism specified in JPA to avoid inconsistencies is a Version field applicable to the entities through the @Version annotation. Once you included the version field in your entities, you can just invoke the merge operation to re-attach detached objects and the container will handle the versioning for you - simple and easy (and safe). The above code can be rewritten in a sound manner: @Override public FpUser update(FpUser entity) throws Exception { return manager.merge(entity); } And that's it, fewer lines of code with a more sound and more robust code. I will fix the code in the footprint repository, so the article readers will find a better code in the repository - and perhaps the java.net staff help me to include an addendum to my article warning the readers about that. At least we both know about that from now on :) Other interesting blogs about similar problems: Some J2EE Performance Tips - from Carol McDonald's Retrying transactions in Java - from Panagiotis Astithas TopLink JPA - from Oracle EclipseLink JPA - it replaces the TopLink in JavaEE 6 Before to release your eyes to a next blogger, let me ask you the intrigant question: What if I care only partially about my Entity locking? It is subject for another blog entry, but during my talk with Mike he confessed the next JPA 2.0 includes this feature: the ability to lock partially an entity. In this way, I don't need to throw an exception in a transaction that will affect minor priority fields (the idea behind the common trap I demonstrated above). People that implement a code to avoid exceptions during updates are actually preventing the client to receive exceptions, resolving manually the locking problems. This suicidal trick seems to make sense where some fields support data overwriting - usually an optional or very low priority data. As soon I got a good example I return to this point, now you are free to give me your feedback or to find something else to have fun on the web. My vacations are over :) time to update my working environment and nothing better than a short blog to warm up my brain to the third quarter of Java in 2009. Next step: to conclude the second part of the article, reviewing the gaps and offering a good quality material of Java EE 5 - the last step before to start my complete migration to Java EE 6. From http://weblogs.java.net/blog/felipegaucho
August 4, 2009
by Felipe Gaúcho
· 27,766 Views
article thumbnail
JPA 2.0 Concurrency and Locking
Optimistic locking lets concurrent transactions process simultaneously, but detects and prevent collisions, this works best for applications where most concurrent transactions do not conflict. JPA Optimistic locking allows anyone to read and update an entity, however a version check is made upon commit and an exception is thrown if the version was updated in the database since the entity was read. In JPA for Optimistic locking you annotate an attribute with @Version as shown below: public class Employee { @ID int id; @Version int version; The Version attribute will be incremented with a successful commit. The Version attribute can be an int, short, long, or timestamp. This results in SQL like the following: “UPDATE Employee SET ..., version = version + 1 WHERE id = ? AND version = readVersion” The advantages of optimistic locking are that no database locks are held which can give better scalability. The disadvantages are that the user or application must refresh and retry failed updates. Optimistic Locking Example In the optimistic locking example below, 2 concurrent transactions are updating employee e1. The transaction on the left commits first causing the e1 version attribute to be incremented with the update. The transaction on the right throws an OptimisticLockException because the e1 version attribute is higher than when e1 was read, causing the transaction to roll back. Additional Locking with JPA Entity Locking APIs With JPA it is possible to lock an entity, this allows you to control when, where and which kind of locking to use. JPA 1.0 only supported Optimistic read or Optimistic write locking. JPA 2.0 supports Optimistic and Pessimistic locking, this is layered on top of @Version checking described above. JPA 2.0 LockMode values : OPTIMISTIC (JPA 1.0 READ): perform a version check on locked Entity before commit, throw an OptimisticLockException if Entity version mismatch. OPTIMISTIC_FORCE_INCREMENT (JPA 1.0 WRITE) perform a version check on locked Entity before commit, throw an OptimisticLockException if Entity version mismatch, force an increment to the version at the end of the transaction, even if the entity is not modified. PESSIMISTIC: lock the database row when reading PESSIMISTIC_FORCE_INCREMENT lock the database row when reading, force an increment to the version at the end of the transaction, even if the entity is not modified. There are multiple APIs to specify locking an Entity: EntityManager methods: lock, find, refresh Query methods: setLockMode NamedQuery annotation: lockMode element OPTIMISTIC (READ) LockMode Example In the optimistic locking example below, transaction1 on the left updates the department name for dep , which causes dep's version attribute to be incremented. Transaction2 on the right gives an employee a raise if he's in the "Eng" department. Version checking on the employee attribute would not throw an exception in this example since it was the dep Version attribute that was updated in transaction1. In this example the employee change should not commit if the department was changed after reading, so an OPTIMISTIC lock is used : em.lock(dep, OPTIMISTIC). This will cause a version check on the dep Entity before committing transaction2 which will throw an OptimisticLockException because the dep version attribute is higher than when dep was read, causing the transaction to roll back. OPTIMISTIC_FORCE_INCREMENT (write) LockMode Example In the OPTIMISTIC_FORCE_INCREMENT locking example below, transaction2 on the right wants to be sure that the dep name does not change during the transaction, so transaction2 locks the dep Entity em.lock(dep, OPTIMISTIC_FORCE_INCREMENT) and then calls em.flush() which causes dep's version attribute to be incremented in the database. This will cause any parallel updates to dep to throw an OptimisticLockException and roll back. In transaction1 on the left at commit time when the dep version attribute is checked and found to be stale, an OptimisticLockException is thrown Pessimistic Concurrency Pessimistic concurrency locks the database row when data is read, this is the equivalent of a (SELECT . . . FOR UPDATE [NOWAIT]) . Pessimistic locking ensures that transactions do not update the same entity at the same time, which can simplify application code, but it limits concurrent access to the data which can cause bad scalability and may cause deadlocks. Pessimistic locking is better for applications with a higher risk of contention among concurrent transactions. The examples below show: reading an entity and then locking it later reading an entity with a lock reading an entity, then later refreshing it with a lock The Trade-offs are the longer you hold the lock the greater the risks of bad scalability and deadlocks. The later you lock the greater the risk of stale data, which can then cause an optimistic lock exception, if the entity was updated after reading but before locking. The right locking approach depends on your application: what is the risk of risk of contention among concurrent transactions? What are the requirements for scalability? What are the requirements for user re-trying on failure? For More Information: Preventing Non-Repeatable Reads in JPA Using EclipseLink Java Persistence API 2.0: What's New ? What's New and Exciting in JPA 2.0 Beginning Java™ EE 6 Platform with GlassFish™ 3 Pro EJB 3: Java Persistence API (JPA 1.0)
August 3, 2009
by Carol McDonald
· 51,446 Views · 1 Like
article thumbnail
Hibernate Performance Tuning
Hibernate is a powerful, high performance object/relational persistence and query service. Hibernate lets you develop persistent classes following object-oriented idiom - including association, inheritance, polymorphism, composition, and collections. Hibernate allows you to express queries in its own portable SQL extension (HQL), as well as in native SQL, or with an object-oriented Criteria and Example API. Quintessential to using any ORM framework like hibernate is to know how to leverage the various performance tuning methods supported by the framework. In this volume Wings Jiang discusses three performance tuning strategies for hibernate: SQL Optimization Session Management Data Caching SQL Optimization When using Hibernate in your application, you already have been coding HQL (Hibernate Query Language) somewhere. For example, “from User user where user.name = ‘John’”. If issuing your SQL statement like this, Hibernate cannot use the SQL cache implemented by database because name of the user, in most scenarios, is extremely distinct. On the contrary, while using placeholder to achieve this, like “from User user where user.name =?” will be cached by the Database to fulfill the performance improvement. You can also set some Hibernate properties to improve performance, such as setting the number of records retrieved while fetching records via configuring property hibernate.jdbc.fetch_size, setting the batch size when committing the batch processing via configuring property hibernate.jdbc.batch_size and switching off the SQL output via setting property hibernate.show_sql to false in product environments. In addition, the performance tuning of your target Database is also significant, like SQL clauses tuning, reasonable indexes, delicate table structures, data partitions etc. Session Management Undoubtedly, Session is the pith of Hibernate. It manages the Database related attributes, such as JDBC connections, data entities’ states. Managing the Session efficiently is the key to getting high performance in enterprise applications. One of the many commonly used and equally elegant approaches to session management in hibernate is to use ThreadLocal. Threadlocal will create a local copy of session for every thread. Thus synchronization problems are averted, when objects are put in the Threadlocal, . To understand how ThreadLocal variables are used in Java, refer to Sun Java Documentation at http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ThreadLocal.html Data Caching Before accomplishing any data caching, it is essential to set the property hibernate.cache.user_query_cache = true. There are three kinds of commonly used Caching Strategies in Hibernate: Using cache based on Session level (aka Transaction layer level cache). This is also called first-level cache. Using cache based on SessionFactory level (Application layer level cache). This is also called second-level cache. Using cluster cache which is employed in distributed application (in different JVMs). In fact, some techniques, like loading data by id, lazy initialization which betokens loading appropriate data in proper time rather than obtaining a titanic number of useless records, which are fairly useless in the subsequent operations are consummated via data caching. First Level Cache (aka Transaction layer level cache) Fetching an object from database always has a cost associated with it. This can be offset by storing the entities in hibernate session. Next time the entities are required, they are fetched from the session, rather than fetching from the database. To clear an object from the session use: session.evict(object). To clear all the objects from the session use session.clear(). Second Level Cache (aka Application layer level cache) In this approach, if an object is not found in session, it is searched for in the session factory before querying the database for the object. If an object is indeed fetched from database, the selected data should be put in session cache. This would improve the performance when the object is required next time. To remove an entity from session factory use the various overloaded implementations of evict() method of SessionFactory. In fact, Hibernate lets you tailor your own caching implementation by specifying the name of a class that implements org.hibernate.cache.CacheProvider using the property hibernate.cache.provider_class. But it is recommended to employ a few built-in integrations with open source cache providers (listed below). Cache Type Cluster Safe Query Cache Supported Hashtable Memory NO YES EHCache Memory, Disk NO YES OSCache Memory, Disk NO YES SwarmCache Clustered YES (clustered invalidation) NO JBoss TreeCache Clustered YES (replication) YES Terracota Clustered YES YES In order to use second level caching, developers have to append some configurations in hibernate.cfg.xml (for example, using EHCache here). net.sf.ehcache.hibernate.Provider In addition, developers also need to create a cache specific configuration file (Example: ehcache.xml for EHCache). (1) diskStore : Sets the path to the directory where cache .data files are created. The following properties are translated: a.user.home - User's home directory b.user.dir - User's current working directory c.java.io.tmpdir (Default temp file path) maxElementsInMemory : Sets the maximum number of objects that will be created in memory. eternal : Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. timeToIdleSeconds : Sets the time to idle for an element before it expires. Is only used if the element is not eternal. Idle time is now - last accessed time. timeToLiveSeconds : Sets the time to live for an element before it expires. Is only used if the element is not eternal. TTL is now - creation time overflowToDisk : Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. Finally the cache concurrency strategy has to be specified in mapping files. For example, the following code fragment shows how to configure your cache strategy. … … Cache Concurrency Strategies There are four kinds of built-in cache concurrency strategies provided by Hibernate. Chosing a right concurrency strategy for your hibernate implementation is the key to cache performance optimization. Besides to ensure data consistency and transaction integrity it is indispensable to master these strategies. read-only If your application needs to read but never modify instances of a persistent class, a read-only cache may be used. This is the simplest and best performing strategy. It's even perfectly safe for use in a cluster. nonstrict-read-write If the application only occasionally needs to update data (For example, if it is extremely unlikely that two transactions would try to update the same item simultaneously) and strict transaction isolation is not required, a nonstrict-read-write cache might be appropriate. read-write If the application needs to update data, a read-write cache might be appropriate. This cache strategy should never be used if serializable transaction isolation level is required. transactional If the application seldom needs to update data and at the same time, application also needs to avoid “dirty read” and “repeatable read”, this kind of concurrency strategy can be employed. The transactional cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. The following table lists cache concurrency strategy supported by various cache providers. Cache Read-only Nonstrict-read-write Read-write Transactional Hashtable YES YES YES N/A EHCache YES YES YES N/A OSCache YES YES YES N/A SwarmCache YES YES N/A N/A JBoss TreeCache YES N/A N/A YES Cluster Cache (in different JVMs) Hibernate also supports cluster caching in disparate JVMs. At present, both SwarmCache and JBoss TreeCache support cluster caching across multiple JVMs. In some situations, especially at the level of enterprise, certain application has to support the concurrency accessing of thousands of users, at that time, cluster cache can help you because the cluster can provide failover and load balancing which improve the performance of application. Points to Note When employing one of the four cache strategies above, pay close attention to the following situation: Data cached almost immutable If data you want to cache is almost constant, you can use data caching which can improve the performance of the application. On the contrary, if the caching data are quiet volatile, Hibernate have to maintain and update the caching over time which extremely leads to performance hit. Data sizes in reasonable range If the size of data you is caching is massive, Hibernate will occupy the most memories of system, which causes the long waiting time of the whole application. Low frequency of data updating If data you are caching needs to be modified frequently, Hibernate have to take an array of time to update and modify the data in caching, which impacts the performance of the application as well. High frequency of data querying If data you are caching is steady, which means that most of the operations are querying, searching, no updating and modifying, making the most use of caching will be affording huge performance improvement. None crucial data Because of existing some incongruities when keeping the data in caching, so if the data you are caching is fairly crucial, do not use caching. By contrast, if the data in caching is insignificant, just use it without any vacillation. Summary Actually, after employing SQL Optimization, Session Management, Data Caching, we will obtain great battalions of performance gains, which make applications achieve acceptable waiting time for the final customers. External Links for Further Study http://www.hibernate.org/hib_docs/reference/en/html/performance.html http://blogs.jboss.com/blog/acoliver/2006/01/23/Hibernate_EJB3_Tuning.txt About Author I am Wings Jiang from BCM China. I have mainly focused on J2EE technologies in recent years and worked in several projects involving Struts/Tapestry, Spring, Hibernate, WebLogic, Websphere, Oracle, DB2 etc. I have experience in design and code of several Java applications. Hibernate performance is one of the areas I pay close heed to in my current working.
June 10, 2009
by Ming Jiang
· 141,861 Views · 4 Likes
article thumbnail
JavaFX: Using Patterns & Clean Code
We are seeing quite a number of exciting JavaFX demos around, demonstrating the pretty features of the language and the capability of easily integrating cool graphics. But, as a software designer, I can't prevent myself from seeing that in most examples we see bloated code - no good separation of concerns and poor applications of the MVC pattern. This is reasonable, as JavaFX was a new language and people needed first to be taught about the syntax and features; but now that - I presume - many of us have been introduced with the new language, it's high time we started worrying about good practices, as well as writing self-commenting code. Let's remember that good practices and good design are always more important than the language! So, let's introduce a very simple project - a Contact List whose specifications are: We have a list of "contacts", where each item is name, last name, email, phone, etc... The UI shows a list of contacts, that can be filtered by a text field; if you enter a value in it, only the contacts whose name starts with the entered text are shown. Selections are applied as you type. Selecting an item in the list of contacts, the details are shown in a form, where you can edit them. At any selection change, the form is animated (a rotation and a blur effect). You can get the code from: svn co -r 37 https://kenai.com/svn/javafxstuff~svn/trunk/ContactList/src/ContactList The model Let's first have a quick look at the model classes. First a simple value object representing a piece of data: package it.tidalwave.javafxstuff.contactlist.model; public class Contact { public var id: String; public var firstName: String; public var lastName: String; public var phone: String; public var email: String; public var photo: String; override function toString() { return "\{id: {id}, value: {firstName} {lastName}, phone: {phone}, email: {email}" } } Then a small service which provides a bunch of data: package it.tidalwave.javafxstuff.contactlist.model; public abstract class ContactRegistry { public abstract function items() : Contact[]; } In the demo code, you'll find a mock implementation with some wired values; in a real case this could be a Business Delegate encapsulating code for retrieving data remotely. So far, so good - it's pretty normal to keep these things separated from the UI. The Controllers We're not going to see a classic Controller here; actually, we're slightly departing from the "pure" MVC. The code I'm showing you is more a "Presentation Model", a pattern described by Martin Fowler as: The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass. This class is basically an hybrid between a classic model and a controller. It is also a façade between the view and the domain model. package it.tidalwave.javafxstuff.contactlist.model; import it.tidalwave.javafxstuff.contactlist.model.ContactRegistry; import it.tidalwave.javafxstuff.contactlist.model.ContactRegistryMock; public class PresentationModel { public var searchText : String; public var selectedIndex : Integer; // The Business Delegate def contactRegistry = ContactRegistryMock{} as ContactRegistry; def allContacts = bind contactRegistry.items(); // The contacts filtered according the contents of the search field public-read def contacts = bind allContacts[contact | "{contact.firstName} {contact.lastName}".startsWith(searchText)]; // The selected contact; the code also triggers a notification at each change public-read def selectedContact = bind contacts[selectedIndex] on replace previousContact { onSelectedContactChange(); }; // Notifies a change in the current Contact selection public-init var onSelectedContactChange = function() { } } Note the extreme compactness brought by functional programming. There's almost no imperative programming as everything is achieved by properly using the binding feature. The only imperative part is the 'onSelectedContactChange' function, which is just a listener to notify selection changes to some external code - it will be used only for triggering the animation. BTW, I'd like to remove it from here, but I wasn't able to. Maybe it's a JavaFX thing that I've not understood yet, but I'm keeping it for another post. Now, everything about the animation goes encapsulated in a specific class, which only exposes two properties controlling the animation: the effect and the rotation angle. A single play() function is provided to start the animation. package it.tidalwave.javafxstuff.contactlist.view; import javafx.animation.Interpolator; import javafx.animation.Timeline; import javafx.scene.effect.GaussianBlur; public class AnimationController { public-read var rotation = 0; public-read def effect = GaussianBlur{} def timeline = Timeline { repeatCount: 1 keyFrames: [ at(0s) { effect.radius => 20; rotation => 45 } at(300ms) { effect.radius => 0 tween Interpolator.EASEBOTH; rotation => 0 tween Interpolator.EASEBOTH } ] } public function play() { timeline.playFromStart(); } } The Views Now, a UI component. The way we design it largely depends on the process, as a graphic designer could be involved. In any case, I think that the whole UI should not be implemented in a single, bloated class; rather relevant pieces should be split apart. For instance, a CustomNode can model the "form" that renders the contact details (in the code below I've omitted all the attributes related to rendering): package it.tidalwave.javafxstuff.contactlist.view; import javafx.scene.CustomNode; import javafx.scene.Group; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.Node; import javafx.ext.swing.SwingLabel; import javafx.ext.swing.SwingTextField; import it.tidalwave.javafxstuff.contactlist.model.Contact; public class ContactView extends CustomNode { public var contact : Contact; public override function create() : Node { return Group { content: [ VBox { content: [ SwingLabel { text: bind "{contact.firstName} {contact.lastName}" } HBox { content: [ SwingLabel { text: "First name: " } SwingTextField { text: bind contact.firstName } ] } HBox { content: [ SwingLabel { text: "Last name: " } SwingTextField { text: bind contact.lastName } ] } HBox { content: [ SwingLabel { text: "Email: " } SwingTextField { text: bind contact.email } ] } HBox { content: [ SwingLabel { text: "Phone: " } SwingTextField { text: bind contact.phone } ] } ] } ] }; } } As you can see, we have only layout and data binding here, the only things a view should do. Putting all together Now the last piece of code, the Main, which builds up the application (again, I've omitted all attributes only related to rendering): package it.tidalwave.javafxstuff.contactlist.view; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.ext.swing.SwingLabel; import javafx.ext.swing.SwingList; import javafx.ext.swing.SwingListItem; import javafx.ext.swing.SwingTextField; import it.tidalwave.javafxstuff.contactlist.controller.PresentationModel; Stage { def animationController = AnimationController{}; def presentationModel = PresentationModel { onSelectedContactChange : function() { animationController.play(); } }; scene: Scene { content: VBox { content: [ HBox { content: SwingLabel { text: "Contact List" } } HBox { content: [ SwingLabel { text: "Search: " } SwingTextField { text: bind presentationModel.searchText with inverse } ] } HBox { content: [ SwingList { items: bind for (contact in presentationModel.contacts) { SwingListItem { text:"{contact.firstName} {contact.lastName}" } } selectedIndex: bind presentationModel.selectedIndex with inverse } ContactView { contact: bind presentationModel.selectedContact effect: bind animationController.effect rotate: bind animationController.rotation } ] } ] } } } As in the previous code snippets, I think the listing can be easily read and understood. Basically, we are glueing all the pieces together and binding the relevant models. In the end, each class in this small project does a simple, cohese thing: representing data, encapsulating the presentation logic, controlling the animation, rendering the views. Dependencies are reduced to the minimum and they have the correct direction: views depend on the models (and not the opposite) and the AnimationController; the AnimationController is independent. You could replace the view components without affecting the rest of the classes, as well as removing or adding other animations by properly using different AnimationControllers. This good separation of roles and responsibilities is the good way to apply OO. There is a detail which is worth discussing. Note the two bind ... with inverse. They implement the so-called "bidirectional binding" where not only a change in the model (e.g. PresentationModel.selectedIndex) is reflected to attributes in the UI (e.g. SwingList.selectedIndex), but also the opposite happens. Indeed, the reverse binding is more important in our example, because it implements the controller responsibility (it captures user's gestures from the view and changes the model); the direct binding from the PresentationModel to SwingList, instead, is useless, as in our case the PresentationModel is never the originator of a change. So, why not using a simple, direct binding in PresentationModel towards SwingList? Such as: public class PresentationModel { var list : SwingList; public def selectedIndex = bind list.selectedIndex; ... } Because this would introduce a dependency from the model/controller to the view, which is plain wrong. Here, bind ... with inverse not only works as a shortcut for writing less code (that is, explicitly declaring a binding and its inverse), but it's also an essential feature for a better design. As far as I know - but I could be wrong - for example in ActionScript (Adobe Flex language) there's no bidirectional binding (you need to put binding keywords at both ends of the association), thus introducing unneeded or circular dependencies. I believe this is true at least at code level (as far as I understand, there are different ways to do binding in ActionScript).
May 12, 2009
by Fabrizio Giudici
· 46,010 Views
article thumbnail
The Four Pillars of ASP.NET
Not that long ago, there was just ASP.NET. But ASP.NET has expanded to include different approaches to development. Recently, I was chatting with Microsoft’s Scott Hunter and Steve Walther over drinks at DevConnections Orlando and Steve mentioned “the four pillars of ASP.NET.” The four pillars are the four ways you can build web sites with ASP.NET, both today and in the future. The four pillars are: 1. ASP.NET Web Forms. Until recently, this was the only pillar of ASP.NET. Everything was done using the familiar rich server-side controls that many have grown to love (and some have learned to despise which is the seed for the other three pillars). So what’s wrong with Web Forms? Well, many developers believe that ASP.NET Web Forms are too much of a black box with a healthy-dose of black magic. There’s a price you pay for the Web Form event model and lifecycle and that price is control over the exchange of data between server and browser. Some say the Web Form model with its incessant ViewState is a pig. The Web Form model also makes it difficult to create testable applications and practice test-driven development (TDD). On the other hand, ASP.NET AJAX and ASP.NET MVC (pillars 2 and 3, respectively) come with a steep learning curve, and for many developers will take longer to develop the equivalent application. Pillar 4 (Dynamic Data), on the other hand, has limited applicability, IMO. My opinion is that with the possible exception of Dynamic Data for the creation of simpler intranet applications, nothing in my mind beats ASP.NET Web Forms (especially when paired with the ASP.NET AJAX UpdatePanel control) for creating good, solid, and responsive applications that, while not the leanest and meanest of applications nor very testable, are easy to grok and master for the novice through advanced developer. Web forms are also the best match for the developer looking to make the move to ASP.NET from Microsoft desktop (Win Forms or WPF) development. And with each new version, Microsoft is making it easier to tame the pig (ViewState) and reduce its size: ASP.NET 2.0 introduced ControlState and ASP.NET 4.0 changes the inheritance model of ViewState so it will be easier to turn off ViewState by default and only turn it on when needed. 2. ASP.NET AJAX. This pillar came to life with the ASP.NET AJAX Extensions for ASP.NET 2.0 / Visual Studio 2005. ASP.NET AJAX is now integrated into ASP.NET and Visual Studio 2008 and consists of both a set of server-side controls as well as the AJAX client-side libraries. In regards to its existence as a “pillar,” I would argue that Microsoft is really only talking about the client-side of ASP.NET AJAX. The reason I say this is that the Upgrade Panel and other server-side AJAX controls merely extend the Web Form pillar, giving Web Form controls the ability to do asynchronous postbacks. There are many in the hard-core ASP.NET AJAX community that believe that a true AJAX application needs to be built from the ground up without the use of Web Forms and the server-side controls. Using this approach, ASP.NET merely becomes a way to emit HTML with embedded JavaScript (and references to the Microsoft ASP.NET AJAX and JQuery libraries) that calls back to ASP.NET (or WCF) web services. When the HTML and JavaScript hit the browser, that’s when the action begins. The promise of this approach is a much snappier user interface and a much more scalable web site. On the downside, this requires programming in a loosely-typed language with a weird inheritance model, spotty support for IntelliSense, and, while improved, lousy debugger support. Another downside, the lack of smart client-side controls is likely to be remedied in the ASP.NET 4.0 timeframe. Microsoft is busy improving the client-side story, complete with client-side controls, for ASP.NET 4.0 (if you are curious, check out http://asp.net/ajax and click on the “ASP.NET AJAX Preview on CodePlex” link for a peek at what’s coming). Regardless, I believe this pillar will always be for a subset of ASP.NET developers who don’t shun the client-side. 3. ASP.NET MVC. This pillar is the newest to emerge from Microsoft. In fact, as of this writing, it’s only a couple of weeks old, having been released at Mix09. Some ASP.NET curmudgeons would call this a throwback to the days of ASP “classic” spaghetti code, but for many others--especially the alt.net crowd and transplants from Ruby and Java--this represents the cat’s pajamas on the Microsoft web stack. (Of course, it’s amazing how quickly developers find problems in the latest programmer’s paradise--usually before its release--and I’m sure the MVC aficionados are already looking to the next release.) The basic idea behind ASP.NET MVC is to separate out the three concerns of the MVC pattern: the model, view, and controller. The model represents the data model, the view is the user interface that presents the data and interacts with the user, and the controller is the command center that takes inputs from the view, pushes and pulls data into/from the model, and decides what to do next. By separating out these concerns (as purely as possible), you improve the ability to create unit tests for your applications and, at least on some level, improve application maintainability. If you are into test driven development, then this is the pillar to hook your horse to. 4. Dynamic Data. IMO, Dynamic Data is a misnomer. From its name, one would tend to think this is yet another data access technology from Microsoft. It is not. I would have preferred Microsoft to use the name Dynamic Application or Dynamic Application Builder. MSDN Help says, “ASP.NET Dynamic Data is a framework that lets you create data-driven ASP.NET Web applications easily.” You start with Dynamic Data by creating a database and then using either LINQ to SQL or the Entity Framework to create a model over your data. Next, create a new project or web site in Visual Studio 2008 (with SP1) using one of the Dynamic Data Web Application templates, make a fairly simple change to the web site’s Global.asax, and Visual Studio builds a dynamic ASP.NET application over your data model. The resulting site support the creation, retrieval, updating, and deletion (commonly referred to as the CRUD operations) of rows in the underlying database. Dynamic Data uses what is termed dynamic scaffolding to construct your application. This means if you change your data model, the application will be instantly updated: there’s no code that needs to be re-generated. Dynamic Data is customizable. Thus, if you don’t like how Dynamic Data presents a datatype or a particular field, or want to change how it performs validation of a field, you can change the templates behind these. You can also change the master page used as well as a number of other details. Kudos to Microsoft for Dynamic Data--even though I hate the name. Just realize that this pillar, unlike the other three, is only applicable to a subset of ASP.NET applications that fit in well with the Dynamic Data approach to applications: applications, which are primarily data-centric, intranet-based applications. That said I could see many places where I might use Dynamic Data, though I am still trying to work through the security implications of opening up the database for pretty much unrestricted reading and writing of database tables. (For those who would like to see an MVC version of Dynamic Data: I’d expect to see such a beast come down the pike at some point from Microsoft.) Conclusion So what does this mean to the developer? I have both good and bad news. The good news is that you now have a choice in how you develop your ASP.NET applications. If you love the responsiveness and coolness of AJAX or you need to scale your applications big-time, then you’ll love ASP.NET AJAX. If, OTOH, you are into unit tests or TDD, you will love ASP.NET MVC. Finally, if you were looking for an easier way to build you basic CRUD web application, you’ll want to take a look at Dynamic Data. Don’t need any of the above? There’s no need to despair--ASP.NET Web Forms are here for the long haul! The bad news is that you now have a choice in how you develop your ASP.NET applications. (Wait a second, wasn’t that also the good news?)This means you have more things to learn. It also means that in trying to support all four pillars, Microsoft may be taking some of its focus off Web Forms. After all, there’s only so many PMs and devs at Microsoft on the ASP.NET team. Furthermore, this means that if you are a manager like me worried about maintainability of applications and hiring developers, your job just got more difficult because one person’s idea of ASP.NET development is not necessarily someone else’s. Still, I think the good news here, outweighs the bad. Microsoft used to present ASP.NET Web Forms vs. MVC as a choice between a car and a motorcycle. Both will get you to your job , but some (the majority of the population, I might add) prefer driving a car, while a sizable minority love their motorcycles which give you better gas mileage and independence, but don’t protect you in the rain. To stretch this analogy to its breaking point, let me suggest that ASP.NET AJAX is like riding a bicycle to work (lean and mean, best gas mileage, but it requires you to exercise for your commute and exposes you to the elements like the motorcycle) while Dynamic Data is like taking the bus to work (let metro do the driving for you.) What about Silverlight? Silverlight is really just the next generation of a one-click desktop application, that is hosted in the browser and runs on a multi-platform .NET virtual machine. Not to take anything away from Silverlight, but it’s not ASP.NET. Does this mean that ASP.NET Web Forms is going away? Although some people “in the know” have stated in the past couple of years that either ASP.NET AJAX or ASP.NET MVC was the future of ASP.NET, this is not the official position of Microsoft. Think about it, since 98%--yes, this is a total educated guess--of ASP.NET development is still done using ASP.NET Web Forms, and this percentage is unlikely to change significantly over the next several years, Microsoft would be stupid to kill off Web Forms. It doesn’t make any economic sense, and since Microsoft is a for-profit entity, I think Web Forms will be a major thrust of ASP.NET for many years to come. In my opinion, Microsoft has added the three new pillars for the following reasons: · Microsoft is always trying to follow innovation and buzz in the industry. Three years ago, that buzz was in AJAX. Today, MVC, separation of concerns, and TDD is all the rage so Microsoft has countered with ASP.NET MVC. · Microsoft is always trying to broaden the appeal of ASP.NET. Microsoft has been trying to woo the open source community for years (after initially discounting it). And in order to do this, it needs to embrace many of the ideals of this community, which tends to live on the bleeding edge and is into AJAX, testability, and TDD, amongst other things. · Microsoft truly wants to improve the productivity of its customers. After all, if you improve the ability of your customers, in our case corporate and independent developers, to get their jobs done, you’ve gone a long way to attracting and retaining customers. In Microsoft’s eyes (and many of its customers), this is a win, win situation. I, for one, would like to thank Microsoft for the four pillars of ASP.NET. In producing the four pillars, Microsoft has given ASP.NET developers the choices they both want and need.
April 30, 2009
by Paul Litwin
· 10,639 Views
article thumbnail
Leader vs Ruler
When I was trying to search for "leaders vs. rulers" on Google, I found many references to governments, royalty, and the military, throughout history. But the strange thing is that none of the articles seemed to distinguish between leaders and rulers. As if leaders and rulers are the same kind of people. They are not. Leaders Last week I was reading the book Tribes, by Seth Godin. In his book Seth says that never in history has it been so easy for anyone to be a leader. These days, with the use of social media, each of us is able to attract our own followers. And on Twitter, this is exactly what we're doing (quite literally). Seth explains that a crowd becomes a tribe when it has a leader that the people are following out of their own free will. And the interesting thing is that people can follow different leaders for different causes. In software projects it is the same. Some people can take the lead on an architectural level, while some have the lead on a functional level. Still others may be the first ones to turn to when people need advice about tools or processes. A complex system does not need a single leader. In fact, I believe a cross-functional team functions best when it has multiple leaders, each with his own area(s) of interest. Rulers In social systems the rulers are of an entirely different breed. While leaders use the power of attraction to convince people what to do, rulers use the power of authority to tell people what to do. Ruling people's lives is the very purpose of the ruler's job. With ruling comes law-making, enforcement and sanctioning, also called the trias politica (legislature, executive, judiciary). Unfortunately, rulers have gotten a bit of a bad name over the centuries. (Much of it deserved, by the way.) But ruling isn't all that bad. Laws, enforcement and sanctions are necessary evils, and in many social systems rulers can peacefully co-exist with leaders. For example: in any football (or soccer) match you will find leaders (one in each team) and rulers (the referees). They all play their parts in making the game work for everyone. Are managers rulers? There's no doubt in my mind that managers are rulers. They are (usually) the only ones with the authority to hire and fire people, and to place them in (or remove them from) teams or departments. They are able to tell people what software to use, what clothes to wear, and how much to pay for a place at the parking lot. Are managers leaders? This is a more interesting question. Lots of management book have been trying hard to turn managers into leaders. The last one I read was Good to Great, by Jim Collins. In his book Jim listed a 5-level hierarchy: Level 5 Executive: Builds enduring greatness through a paradoxical blend of personal humility and professional will. Level 4 Effective Leader: Catalyzes commitment to and vigorous pursuit of a clear and compelling vision, stimulating higher performance standards. Level 3 Manager: Organizes people and resources toward the effective and efficient pursuit of pre-determined objectives. Level 2 Contributing Team Member: Contributes individual capabilities to the achievement of group objectives and works effectively with others in a group setting. Level 1 Highly Capable Individual: Makes productive contributions through talent, knowledge, skills, and good work habits. The problem I have with Jim's hierarchy is that it suggests a linear progression to "higher" levels (where a leader is on a "higher" level than a manager). This doesn't fit with my observations of how social networks operate. In a software project, or any other social network, there can be many leaders, each with his or her own goals and desires. Some are taking initiatives for better architectures, some are leading the way to better user interface design, and some are guiding their followers towards better customer service, better processes, better software tools, or better coffee. To be a leader is not the next step for managers It is the manager's job to give room to leaders There are thousands of leaders on Twitter, and they all have their own huge numbers of followers. But who are the managers of Twitter? Only Evan Williams, Biz Stone and Jack Dorsey are. It's their platform. It's their game. They are the referees, making the laws, enforcing them, and sanctioning, while thousands of leaders and tribes are running around trying to score. Sure, it's ok when managers are trying to be leaders. Nothing wrong with that. Evan, Biz and Jack have a large number of followers themselves too. But they don't have the largest tribes. Managers are on top of things, but they are not on top. Rulers don't need to have the largest tribes themselves. Being a great ruler is hard enough already. If you think you need to be a great leader too, you're just making it hard for yourself. Referees contribute to great football/soccer games by being great rulers. They don't attempt to lead. It's not their job. They are in charge, but they are not the ones with the biggest egos. In his presentation Step Back from Chaos Jonathan Whitty shows that managers are often not the hubs in a social network. It's the informal leaders in a network through which most of the communication flows. It's the managers' job to make sure that leadership is cultivated, and that the emerging leaders are following the rules. So, you can be a leader, or you can be a ruler. And if you're exceptionally talented, perhaps you can be both. Which one will you be?
April 28, 2009
by Jurgen Appelo
· 6,626 Views
article thumbnail
Making Distinctions Between Different Kinds of JSF Managed-Beans
JSF has a simple Inversion-of-Control (IoC) container called the JSF Managed Bean Facility (MBF). Although it has a verbose XML syntax, and is not as robust as the Spring BeanFactory, PicoContainer, or the JBoss Microcontainer, the MBF does have the basics of an IoC container, and offers features like dependency injection. When a POJO is managed by the JSF MBF, it is typically referred to as a managed-bean. But if you're going to create a maintainable JSF webapp/portlet, it is necessary to distinguish between different kinds of managed-beans. This practice will also preserve the clean separation of concerns that JSF provides by implementing the Model-View-Controller (MVC) design pattern: Managed-Bean Type Nickname Typical Scope Model Managed-Bean model-bean session Description: This type of managed-bean participates in the "Model" concern of the MVC design pattern. When you see the word "model" -- think DATA. A JSF model-bean should be a POJO that follows the JavaBean design pattern with getters/setters encapsulating properties. The most common use case for a model bean is to be a database entity, or to simply represent a set of rows from the result set of a database query. Backing Managed-Bean backing-bean request Description: This type of managed-bean participates in the "View" concern of the MVC design pattern. The purpose of a backing-bean is to support UI logic, and has a 1::1 relationship with a JSF view, or a JSF form in a Facelet composition. Although it typically has JavaBean-style properties with associated getters/setters, these are properties of the View -- not of the underlying application data model. JSF backing-beans may also have JSF actionListener and valueChangeListener methods. Controller Managed-Bean controller-bean request Description: This type of managed-bean participates in the "Controller" concern of the MVC design pattern. The purpose of a controller bean is to execute some kind of business logic and return a navigation outcome to the JSF navigation-handler. JSF controller-beans typically have JSF action methods (and not actionListener methods). Support Managed-Bean support-bean session / application Description: This type of bean "supports" one or more views in the "View" concern of the MVC design pattern. The typical use case is supplying an ArrayList to JSF h:selectOneMenu drop-down lists that appear in more than one JSF view. If the data in the dropdown lists is particular to the user, then the bean would be kept in session scope. However, if the data applies to all users (such as a dropdown lists of provinces), then the bean would be kept in application scope, so that it can be cached for all users. Utility Managed-Bean utility-bean application Description: This type of bean provides some type of "utility" function to one or more JSF views. A good example of this might be a FileUpload bean that can be reused in multiple web applications. Now... One of the main benefits in making fine distinctions like this is loose coupling. What's that you ask? Well let's first take a look at an example of tight coupling, where MVC concerns can be smashed/confused into a single managed-bean: public class ModelAndBackingAndControllerBean { private String fullName; // model-bean property private boolean privacyRendered; // backing-bean property // model-bean getter public String getFullName() { return fullName; } // model-bean setter public void setFullName(String fullName) { this.fullName = fullName; } // backing-bean getter public boolean isPrivacyRendered() { return privacyRendered; } // backing-bean setter public void setPrivacyRendered(boolean privacyRendered) { this.privacyRendered = privacyRendered; } // backing-bean actionListener for UI support logic public void togglePrivacySection(ActionEvent actionEvent) { privacyRendered = !privacyRendered; } // controller-bean business logic public String submit() { System.out.println("fullName=" + fullName); return "success"; } } The problem here is that the bean would have to be kept in session scope because of the model-bean property. Additionally, what if we wanted to do some unit testing with mock model data? Can't do it. So in order to fix these problems, and to promote loose coupling, we would have three separate Java classes: public class ModelBean { private String fullName; public void setFullName(String fullName) { this.fullName = fullName; } public String getFullName() { return fullName; } } public class BackingBean { private boolean privacyRendered; public void setPrivacyRendered(boolean privacyRendered) { this.privacyRendered = privacyRendered; } public boolean isPrivacyRendered() { return privacyRendered; } public void togglePrivacySection(ActionEvent actionEvent) { privacyRendered = !privacyRendered; } } public class ControllerBean { private ModelBean modelBean; public ModelBean getModelBean() { return modelBean; } public void setModelBean(ModelBean modelBean) { // Dependency injected from the JSF managed-bean facility this.modelBean = modelBean; } public String submit() { System.out.println("fullName=" + getModelBean().getFullName()); return "success"; } } Now that the beans are found in different classes, they can all be kept in their appropriate scopes. The model-bean can be kept in session scope, and the backing-bean and controller-bean can be kept in request scope, thus saving memory resources on the server. Finally, we can use the dependency injection features of the JSF MBF in order to inject the model-bean into the controller-bean. This can be seen in the following WEB-INF/faces-config.xml example, where the #{modelBean} Expression Language (EL) binding is used: modelBean myproject.ModelBean session backingBean myproject.BackingBean request controllerBean myproject.ControllerBean request modelBean #{modelBean} From http://blog.icefaces.org/
April 24, 2009
by Neil Griffin
· 64,086 Views · 2 Likes
  • Previous
  • ...
  • 874
  • 875
  • 876
  • 877
  • 878
  • 879
  • 880
  • 881
  • 882
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×