Return-Path: Delivered-To: apmail-openjpa-users-archive@locus.apache.org Received: (qmail 20650 invoked from network); 30 Oct 2008 15:45:04 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 30 Oct 2008 15:45:04 -0000 Received: (qmail 96701 invoked by uid 500); 30 Oct 2008 15:45:09 -0000 Delivered-To: apmail-openjpa-users-archive@openjpa.apache.org Received: (qmail 96680 invoked by uid 500); 30 Oct 2008 15:45:09 -0000 Mailing-List: contact users-help@openjpa.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@openjpa.apache.org Delivered-To: mailing list users@openjpa.apache.org Received: (qmail 96669 invoked by uid 99); 30 Oct 2008 15:45:09 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 30 Oct 2008 08:45:09 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of jandockx@gmail.com designates 74.125.78.24 as permitted sender) Received: from [74.125.78.24] (HELO ey-out-2122.google.com) (74.125.78.24) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 30 Oct 2008 15:43:54 +0000 Received: by ey-out-2122.google.com with SMTP id 25so220880eya.57 for ; Thu, 30 Oct 2008 08:44:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:from:to :content-type:content-transfer-encoding:mime-version:subject:date :x-mailer; bh=S7QyHdKl4qRip5Cv2FL5FXcc37bjoWnXtG7UOq0tO88=; b=bOcm/vWGqT5TrujdSUtHbmW01PeuxSGnmut9I4EoRB1YDy0gctlsv+pY0nPYm9r8uM bL0qYL1yaGyf2C4Fhy2HchiqYFHVXmwMg2ComyEbuPyH+NHpBCKSabwNDam0rhQHq3lP Xa9p7qEG6uKxfplJat0TWuSgrezsHWrz+kTts= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:from:to:content-type:content-transfer-encoding :mime-version:subject:date:x-mailer; b=cs5xpkjrsCA1pxDElcWMjvn9kFDi+lT1HpTY3mgLfZ8DFaDnI5QX2CHAaM1ofg3Ulr tsx+dQr5eilghKznGC0wDjCa33k3qSHCpagI1AIp3IMrr9DAAmmr2fuHXec6Uv7VGv7h wUQwAJaBMvWDZ5w/Owl8A/Gdb1JHmrwnsONpA= Received: by 10.210.44.1 with SMTP id r1mr11822220ebr.179.1225380850245; Thu, 30 Oct 2008 08:34:10 -0700 (PDT) Received: from ?10.0.2.201? (mxtreme.arista.be [81.246.61.75]) by mx.google.com with ESMTPS id t12sm2771879gvd.10.2008.10.30.08.34.07 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 30 Oct 2008 08:34:08 -0700 (PDT) Message-Id: <1E322C47-1ACB-4EAF-BD47-847F7E5870F9@gmail.com> From: Jan Dockx To: users@openjpa.apache.org Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v929.2) Subject: Suggestion: @Column with ValueHandlers that use multiple columns Date: Thu, 30 Oct 2008 16:34:06 +0100 X-Mailer: Apple Mail (2.929.2) X-Virus-Checked: Checked by ClamAV on apache.org We suggest a change in how OpenJPA determines the names to be used for DB columns when using value handlers that use multiple columns. When a @Column annotation (or the equivalent in XML) is found for a property or field that is handled by a value handler, the name passed to the map() method should be the name in the annotation, and not the name of the property or field. While working with ValueHandlers that use multiple columns, we found the following behavior (using OpenJPA on WebSphere 6.1..., thus OpenJPA 1.0.3. (?)): For a developer of an entity that uses the complex value type for which we write the value handler, the complex value type is "one thing". She doesn't (want to) know the internal complexity. The goal of complex value types is indeed encapsulation. The developer of the entity also does not (want to) know on how many and which columns we want to persist. The name given as parameter in the map() function of a ValueHandler is the name of the underlying property / field. It is the intention to define names on the Columns we return that are distinct for the different columns, in the context of any use (i.e., for many different properties that use our complex value type, in many different entities, by many different developers). Therefor it is not a bad idea to name the columns something like name + "_subcolumndescription". E.g., we have a TimeInterval complex value type, that features a begin and end property. We want, in particular circumstance, to persist time intervals in 2 TIMESTAMP columns, called name + "_begin" and name + "_end". When applied to a property / field called "subscriptionPeriod", you thus get in the database the columns "SUBSCRIPTIONPERIOD_BEGIN" and "SUBSCRIPTIONPERIOD_END". So far, so good. Now, for several good reasons, developers might want to override the (base) name used for column names. We don't want to use the name of the field / property, but something else (particularly handy when your style uses a prefix for instance variables like "$" or "_"). This is supported in JPA with the @Column() annotation. Now, we observe that when we combine this annotation with the OpenJPA value handlers, that we get an error, because we have only defined 1 column name, and we need n for our property. The solution is to use the OpenJPA @Columns({}) annotation, where we can nest a @Column() annotation with a specific name for each column. In our example, suppose we want to use "SUBSRC" as column name: @Column("SUBSCR") gives an error and @Columns({@Column("SUBSCR_BEGIN"), @Column("SUBSCR_END")}) gives indeed 2 columns with those names in the database. The naming is then dependent on the order. We suggest that this breaks encapsulation. To make this work, the developer indeed needs to be aware of the internal of TimeIntervalValueHandler. We suggest a small change in OpenJPA: when calling the map() method, give as name the name of the property / field if no @Column() annotation is found, or if the @Columns() annotation is found (although then it is irrelevant, but passing null is not a backward compatible option). This is the current behavior. In the case the @Column() annotation (or the equivalent in XML) is found however, pass in the name given in the annotation as name parameter to the map() method, instead of the current property / field name. Also, the verification would have to be changed to not throw an error in this case. The behavior with @Columns() should be kept as fallback for legacy databases (although in that case you probably will not be working with complex value types and value handlers?).