Phát triển Java 2.0: Chào Google App Engine Phát triển ứng dụng Web nhanh chóng bằng cách sử dụng Groovy, Eclipse và JDO Andrew Glover , Tác giả và nhà phát triển, ThirstyHead.com Tóm t
Trang 1Phát triển Java 2.0: Chào Google App Engine
Phát triển ứng dụng Web nhanh chóng bằng cách sử dụng Groovy, Eclipse và JDO
Andrew Glover , Tác giả và nhà phát triển, ThirstyHead.com
Tóm tắt: Các giải pháp nguồn mở và các cơ sở hạ tầng vay mượn đang thay đổi
đặc điểm của việc phát triển Java™, cho phép bạn cung cấp phần mềm tốt hơn,
nhanh chóng hơn và với chi phí thấp Andrew Glover, khi đặt ra thuật ngữ Java development 2.0 (phát triển Java 2.0) để gói gọn sức mạnh tích lũy của các hiện
tượng này, đã khởi đầu một loạt bài viết mới về một số công cụ và công nghệ có liên quan Bài viết đầu tiên này báo hiệu thời kỳ phát triển Java 2.0 đã tới và giải thích cho bạn cách để có thể làm cho những khái niệm của nó đơm hoa kết trái nhanh chóng với Google App Engine (Máy ứng dụng của Google) cho Java
Thế giới Java là một hệ sinh thái phong phú với một bố cục trải rộng gồm các nhà phát triển, các doanh nghiệp và — quan trọng nhất — các ứng dụng, nhiều ứng dụng đã hoàn thiện trong hơn một thập kỷ qua Cộng đồng Java trên toàn thế giới
đã đầu tư rất nhiều tiền bạc, thời gian và trí lực vào nền tảng này và những đóng góp này đã mang lại một kho tàng giàu có các công cụ mã nguồn mở và các công
cụ thương mại, các khung công tác, và thực sự cả các giải pháp, rất thành công
Hàng loạt đầu tư như nói trên vào nền tảng Java đã thay đổi cách phát triển Java một cách khéo léo Hai xu hướng chính đang thay đổi nhanh chóng đặc điểm của nó:
Về loạt bài này
Bối cảnh phát triển Java đã thay đổi căn bản kể từ công nghệ Java đầu tiên xuất hiện Nhờ sự hoàn thiện các khung công tác mã nguồn mở và các cơ sở hạ tầng triển khai cho-thuê đáng tin cậy, giờ đây có thể lắp ráp, thử nghiệm, chạy và bảo trì các ứng dụng Java một cách nhanh chóng và không tốn kém Trong loạt bài này, Andrew Glover khám phá một loạt các công nghệ và các công cụ làm cho mô hình phát triển Java mới này trở thành có thể
Lợi dụng hoàn toàn các công cụ và các khung công tác mã nguồn mở để
xây dựng các ứng dụng từ trên xuống dưới
Thuê (hoặc mượn) các cơ sở hạ tầng ứng dụng cần thiết ở mọi cấp độ để quản lý vòng đời phần mềm, bao gồm cả việc tự chạy các ứng dụng
Trang 2Không khía cạnh nào trong những gì tôi gọi phát triển Java 2.0 là mới hoặc cách
mạng, nhưng các công nghệ cho phép đã hoàn thiện đến mức bây giờ đã có thể, như chưa từng có trong lịch sử của công nghệ Java, lắp ráp các ứng dụng tốt hơn
một cách nhanh chóng và rẻ — chắc chắn là một trong những mong muốn trên hết
của các doanh nghiệp trên thế giới
Bài viết này khởi đầu một loạt bài viết mới sẽ tìm hiểu việc phát triển Java 2.0 sâu hơn Bạn sẽ tìm hiểu về việc xây dựng và triển khai các ứng dụng Web với EC2 của Amazon, sử dụng Google App Engine (máy ứng dụng của Google), sử dụng CouchDB (đang được gọi là cơ sở dữ liệu cho Web) và các công cụ và các công nghệ khác cung cấp các khối xây dựng để lắp ráp, thử nghiệm và triển khai các ứng dụng nhanh gọn và chi phí ít tiền hơn so với từ trước đến bây giờ
Điểm dừng đầu tiên: Google App Engine cho Java (xem Tài nguyên) Tôi sẽ giới thiệu cho bạn nền tảng này bằng phương pháp "Hello World" (Xin chào Thế giới) truyền thống, sau đó chỉ cho bạn cách tạo một ứng dụng Web hoạt động bằng cách
sử dụng Groovy, Java Data Objects (JDO-Các đối tượng dữ liệu Java) và trình cắm thêm Eclipse cho Google App Engine Tuy nhiên, theo trình tự, trước tiên hãy xem tổng quan nhanh về giá trị kinh doanh của việc phát triển Java 2.0
Nhanh và rẻ
Các từ nhanh và rẻ thường không được kết hợp với việc phát triển Java Trong
thực tế, chúng thường gợi lên các ấn tượng về phát triển phần mềm ít quan trọng
— tầm nhìn của các công ty nhỏ có ít nguồn lực Tuy nhiên, sự thật của vấn đề là CNTT là một trọng tâm chi phí đối với nhiều công ty (lớn và nhỏ), thúc đẩy họ giữ cho các chi phí CNTT thấp trong khi rút ra càng nhiều giá trị càng tốt
Đó là nơi việc phát triển Java 2.0 vào cuộc Bằng cách sử dụng các công cụ mã nguồn mở, các khung công tác và thậm chí các giải pháp, các công ty có thể lắp ráp các ứng dụng phần mềm nhanh chóng vì họ không phải tự mình viết nhiều mã lệnh Khi lần đầu tiên tôi bắt đầu phát triển phần mềm bằng công nghệ Java hơn
10 năm trước đây, phạm vi của các công cụ và các khung công tác có sẵn cho các nhà phát triển nhỏ bé hơn nhiều Một số ít các công cụ đó cũng không có sẵn miễn phí Bạn phải mua một IDE, một cơ sở dữ liệu, một khung công tác ánh xạ đối tượng-quan hệ (ORM) (ôi chết tiệt, bạn có thể đã phải mua trình điều khiển cần thiết để giao tiếp với cơ sở dữ liệu của bạn) và dĩ nhiên, các máy để triển khai ứng dụng của bạn trên đó Bây giờ? Tất cả mọi thứ mà tôi vừa liệt kê (và nhiều hơn nữa) là có sẵn miễn phí và chất lượng cao
Hơn nữa, bằng cách vay mượn cơ sở hạ tầng (ví dụ như những cơ sở hạ tầng được EC2 của Amazon hoặc Google App Engine cung cấp), bạn có thể triển khai ứng dụng khá rẻ (so với mua toàn bộ cơ sở hạ tầng cần thiết)
Trang 3Xây dựng, mua, hay mượn: Đó là câu hỏi mới
Nhiều doanh nghiệp có cả một danh sách phần cứng để chạy các ứng dụng như các
cơ sở dữ liệu, các máy chủ ứng dụng, các hệ thống quản lý thay đổi và các công cụ lần vết tìm lỗi Tuy vậy, ngày nay, danh sách này có thể dễ dàng vứt bỏ để thay bằng việc sử dụng chính gói phần mềm ấy dưới dạng một dịch vụ đang chạy trên một cơ sở hạ tầng của người nào đó khác
Toàn bộ chồng ứng dụng mà một nhóm làm việc có thể phải sử dụng để quản lý một quá trình phát triển có thể được vay mượn — nghĩa là, thuê với một khoản phí nhỏ — giải phóng cho công ty khỏi phải đầu tư vào phần cứng để chạy chúng Ví
dụ, thay vì mua một máy tính để chạy một hệ thống quản lý thay đổi (như
Subversion hoặc Git, cả hai là mã nguồn mở và có sẵn miễn phí), một nhóm làm việc có thể sử dụng một dịch vụ quản lý thay đổi dùng chung như GitHub Công ty đằng sau GitHub phải gánh chịu chi phí của các tài sản phần cứng và tính một chi phí danh nghĩa (thường là hàng tháng cho mỗi người dùng) cho các tổ chức khác
sử dụng Git Cùng một nguyên tắc thuê phần mềm như là một dịch vụ từ các nhà cung cấp khác như thế này có thể được áp dụng cho việc lần vết tìm lỗi, quản lý các bài kiểm thử và quản lý các yêu cầu (ví dụ qua JIRA Hosted hoặc Pivotal Tracker)
Cũng có thể nói giống như vậy đối với các tài sản phần cứng nằm dưới mà các nền tảng phần mềm khác (về bản chất, thường là tùy chỉnh) chạy trên đó Một doanh nghiệp có thể vứt bỏ phần cứng nằm bên dưới của một ứng dụng web cụ thể để thay bằng việc chạy ứng dụng trên phần cứng được cung cấp bởi Amazon, Google
hoặc các đối tác khác Các công ty này đưa ra khả năng thuê phần cứng ở các mức
độ khác nhau, vừa vặn có thể lưu trữ một ứng dụng Hơn nữa, các công ty này quản lý khả năng mở rộng, sao lưu và thậm chí cả an ninh nữa Hãy suy nghĩ về nó một lát: Amazon và Google đã nêu ra những mối quan tâm này (và nhiều hơn nữa)
từ lâu rồi và đối phó tốt hơn với chúng, có nhiều đổi mới xung quanh các khía cạnh của việc chạy các nền tảng phần mềm sao cho hiệu quả (Đó là đúng Hãy đương đầu với nó)
Bằng cách sử dụng App Engine của Google, ví dụ thế, một công ty CNTT có thể
hạ thấp tổng chi phí mua một cơ sở hạ tầng để chạy các ứng dụng cần thiết Và họ
có thể triển khai các ứng dụng đó nhanh hơn vì vô số các mối quan tâm đan chéo nhau, kết hợp với việc triển khai ứng dụng và quản lý đã được tính đến và vì thế được cung cấp cho họ (với nhiều khả năng là theo một cách tốt hơn)
Nhanh và rẻ không còn có nghĩa là chất lượng thấp Ngược lại, phát triển Java 2.0
là một cách tiếp cận chiến thuật đã giả định một quy trình vững chắc để nhấn mạnh chất lượng
Trang 4
Một ngày đơn giản với App Engine của Google
App Engine của Google là một nền tảng thực sự để xây dựng và triển khai ứng dụng Web Java (và Python) trên cơ sở hạ tầng mở rộng của Google Nó không yêu cầu lệ phí cấp phép sử dụng (tất nhiên, trừ ra một số thư viện phần mềm mà bạn chọn để sử dụng trên cơ sở hạ tầng ấy yêu cầu giấy phép) và không cần chi phí trả trước cho băng thông hoặc không gian lưu trữ Cơ sở hạ tầng của App Engine là hoàn toàn miễn phí cho đến khi bạn đạt đến ngưỡng về mức sử dụng — dung lượng lưu trữ 500MB và, theo như trích dẫn nguyên văn từ Google, "đủ CPU và băng thông cho khoảng 5 triệu lượt xem trang mỗi tháng" Chỉ cần nói rằng, khi bạn đạt tới điểm mà Google bắt đầu gửi hóa đơn tính phí cho bạn, ứng dụng Web của bạn rõ ràng đã tạo ra lưu lượng đáng kể (và do đó có lãi)
Dựng lên một ứng dụng và chạy nó trên App Engine không thể dễ dàng hơn nữa Google thậm chí còn cung cấp một trình cắm thêm Eclipse xử lý gần như mọi thứ cho bạn Và trình cắm thêm này bao gồm các thành phần thiết yếu của một ứng dụng servlet "Hello World" để giúp bạn bắt đầu với nền tảng này Trong bài giới thiệu nhập môn gần đây của ông trên developerWorks ("App Engine của Google cho Java, Phần 1: Tăng tốc nó!") Rick Hightower sẽ đưa bạn qua từng bước triển khai ứng dụng Hello World (bao gồm các ảnh chụp màn hình) Nếu bạn chưa từng làm việc theo bài viết của Rick, hãy làm theo các bước sau:
Xác định phiên bản
Các triển khai App Engine có thể được định phiên bản — đó là, bạn có thể gán một mẫu chuỗi ký tự (biểu hiện một phiên bản) cho một bản triển khai Điều này
có ích khi bạn bắt đầu có nhiều bản phát hành Thông qua các URL và bảng điều khiển của Google, bạn có thể mô tả phiên bản nào là phiên bản "hoạt động" và phiên bản nào không phải là phiên bản hoạt động (mặc dù bất kỳ bản triển khai đã xác định phiên bản nào đều vẫn có thể truy cập qua một URL, với điều kiện bạn chưa gỡ bỏ nó trước) Theo đó, bất cứ lúc nào bạn muốn triển khai một phiên bản mới của dự án của bạn lên cơ sở hạ tầng của Google, bạn phải cung cấp cho bản triển khai đó một mã hiệu phiên bản hợp lệ Mẫu chuỗi ký tự không được bao gồm các dấu chấm câu (1.1 không dùng được, nhưng 1-1 lại dùng được) Bạn có thể gán các phiên bản trong tệp AppEngine-web.xml, có trong thư mục war/WEB-INF
đã được sinh ra khi bạn tạo lập một dự án mới Để triển khai dự án đầu tiên của mình, bạn không cần phải đối phó với các phiên bản (chưa cần) vì Google chỉ định một phiên bản khởi đầu là 1 trong tệp appengine-web.xml đã tạo ra
Trang 51 Hãy tạo một tài khoản App Engine của Google (nó là miễn phí) bằng cách
nhấn vào liên kết Sign up (Đăng nhập) trong Getting Started (Bắt đầu)
trên trang http://code.google.com/appengine/
2 Tải xuống trình cắm thêm App Engine của Google cho Eclipse từ
http://code.google.com/appengine/downloads.html và cài đặt nó
3 Tạo một dự án mới bằng cách nhấn vào nút New Web Application Project
(Dự án ứng dụng Web mới) trong Eclipse, trong hộp thoại kết quả, bỏ dấu chọn của tùy chọn Use Google Web Toolkit (sử dụng dụng cụ Web của Google) Đặt tên dự án và gói tương ứng là bất cứ cái gì bạn muốn
4 Chọn dự án của bạn trong hệ thống phân cấp và nhấn vào nút Deploy App Engine Project (Triển khai dự án App Engine)
5 Nhập mã ủy quyền của bạn (là cái mà bạn đã sử dụng khi tạo ra một tài khoản App Engine trong Bước 1)
6 Kết hợp dự án cục bộ của bạn với mã nhận dạng (ID) của ứng dụng mà bạn tạo ra khi bạn bước đầu tạo một tài khoản App Engine (Bạn có thể có đến
10 ID)
7 Nhấn vào nút Deploy (Triển khai) Bạn sẽ thấy rất nhiều văn bản trôi qua
trên bàn điều khiển Eclipse (trình cắm thêm đang thực hiện rất nhiều đằng sau hậu trường bao gồm việc cải tiến mọi lớp cần thiết nào để sử dụng dịch
vụ lưu trữ-dữ liệu rất ấn tượng của Google) Khi tiếng ồn dịu dần (và tất cả mọi thứ đã làm việc đúng), bạn sẽ thấy một thông báo kết thúc bằng dòng chữ "Việc triển khai đã hoàn tất thành công."
8 Đi tới trang tài khoản App Engine của bạn tại Google và tìm liên kết
Versions trên bảng điều khiển của Google Ở đó bạn sẽ thấy phiên bản đã
triển khai của bạn và URL tương ứng của nó Nhấn vào URL và sau đó nhấn vào liên kết tới servlet đã tạo ra để thấy dòng chữ "Hello, world" (Xin chào, thế giới) buồn tẻ nhưng lại làm bạn hài lòng làm sao, được in ra dạng văn bản
Ít dòng mã hơn với Groovlets
Bạn đã triển khai thành công ứng dụng Google App Engine đầu tiên của bạn và bạn đã không viết một dòng mã nào Thực vậy, nếu bạn có kế hoạch sử dụng App Engine, bạn sẽ đi đến chỗ viết một số dòng mã — nhưng hãy nhớ rằng, đã có
nhiều mã ở đó mà bạn có thể tái sử dụng để làm cho công việc của bạn dễ dàng hơn Mã tái sử dụng đó có thể là các dịch vụ mà Google cung cấp (chẳng hạn như
Trang 6các dịch vụ tài khoản Google hoặc dịch vụ lưu trữ dữ liệu của nó) hoặc các thư viện nguồn mở đã được chuyển đến để làm việc trên cơ sở hạ tầng của Google Việc dùng lại mã của người khác thường có nghĩa là bạn viết mã ít hơn — và ít mã hơn rất có thể có nghĩa là có ít lỗi hơn
Một trong những thư viện nguồn mở yêu thích của tôi (và thực ra là các nền tảng) hầu như luôn dẫn đến ít dòng mã hơn để tạo ra các ứng dụng làm việc là Groovy (xem Tài nguyên) Nhóm Groovy gần đây đã phát hành các phiên bản của nền
tảng này để làm việc trên App Engine, cho phép bạn sử dụng Groovlets thay vì các
servlet làm cho một ứng dụng hoạt động nhanh gọn Groovlets là các kịch bản lệnh Groovy đơn giản hành động như các servlet Vì bạn đã có một servlet để in
"Hello, world", tôi sẽ chỉ cho bạn cách làm điều tương tự với một Groovlet sẽ dễ dàng như thế nào (và bạn sẽ thấy Groovy cho phép ít hơn bao nhiêu dòng mã) Việc triển khai một Groovlet trên App Engine với trình cắm thêm Eclipse diễn ra theo một vài bước đơn giản:
1 Tải về phiên bản mới nhất của Groovy (tại thời điểm bài viết này là 1.6.3)
từ http://groovy.codehaus.org/Download
2 Tìm tệp groovy-all-1.6.3.jar và đặt nó vào thư mục war/WEB-INF/lib của
dự án App Engine của bạn Tiện thể, trong thư mục này, bạn có thể đặt bất
kỳ thư viện nào mà ứng dụng của bạn yêu cầu (với một số cảnh báo mà tôi
sẽ trình bày ngay sau đây)
3 Thêm các câu trong Liệt kê 1 (để ánh xạ Groovlets tới các yêu cầu chuyên dùng) vào tệp web.xml, có trong thư mục war/WEB-INF:
Liệt kê 1 Cập nhật tệp web.xml để hỗ trợ Groovlets
<servlet>
<servlet-name>GroovyServlet</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>
<servlet-mapping>
Trang 7<servlet-name>GroovyServlet</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>
4 Thêm một thư mục groovy vào thư mục WEB-INF của bạn; đây là nơi bạn
sẽ lưu Groovlets của mình Trong thư mục groovy, tạo một tệp mới gọi là helloworld.groovy Trong tệp mới đó, gõ nhập println "Hello, Groovy baby!"
5 Cập nhật phiên bản của ứng dụng của bạn — gọi là 1-1 — và triển khai lại Tìm URL tương ứng qua bảng điều khiển Google và sau đó lướt tới
/helloworld.groovy trong trình duyệt của bạn và thưởng thức sự lộng lẫy của một thông báo hợp thời được in từ Groovy trên cơ sở hạ tầng của
Điều đó thật dễ dàng, phải không? Tất cả những thứ mà bạn phải làm chỉ là thêm vào Groovy JAR, cập nhật tệp web.xml, tạo một thư mục groovy mới, viết một Groovlet và triển khai nó Bạn có nhận thấy Groovlet đã làm cũng những việc
tương tự như servlet mặc định mà trình cắm thêm đã tạo ra nhưng chỉ trong một dòng mã không? Bạn chọn sẽ phải viết và duy trì cái nào: một lớp lớn hay một lớp
nhỏ mà làm cùng một việc?
Groovy + Java = ứng dụng hoạt động Rất nhanh chóng
Bây giờ tôi sẽ chỉ cho bạn việc sử dụng Groovy cùng với App Engine của Google
có thể mang lại một ứng dụng hoạt động nhanh gọn như thế nào Tôi sẽ sử dụng một trang HTML đơn giản, một Groovlet và một lớp Java có tăng cường JDO để lưu giữ lâu bền một sự kiện (trong trường hợp này, một cuộc thi ba môn phối hợp) Tôi sẽ giữ cho nó đơn giản vào lúc này, nhưng bạn sẽ thấy rằng ứng dụng này có thể phát triển thêm để bao gồm các đặc tính khác và trong các bài viết tiếp theo của loạt bài này bạn sẽ thực hiện chúng (tất nhiên, sử dụng các cơ sở hạ tầng và các công nghệ khác)
JDO nhanh
Trang 8Google App Engine cung cấp khả năng để lưu giữ lâu bền dữ liệu khi sử dụng JDO, là một tiêu chuẩn Java cho lưu giữ lâu bền (xem Tài nguyên) Đối với hầu hết các nhà phát triển Java, lưu giữ lâu bền dữ liệu thường ngụ ý việc ghi lưu thông tin vào một cơ sở dữ liệu quan hệ; tuy nhiên, trong trường hợp của Google,
cơ chế lưu trữ nằm dưới là sở hữu độc quyền của Big Table, không phải là cơ sở
dữ liệu quan hệ Điều vừa nói không thực sự quan trọng: các chi tiết về cách
Google lưu giữ lâu bền các thuộc tính cụ thể phần lớn được ẩn dấu với bạn Chỉ cần nói rằng, bạn có thể sử dụng các đối tượng Java bình thường (hoặc các đối tượng Groovy, cho vấn đề này) để xây dựng một ứng dụng có thể lưu trữ thông tin như bạn sẽ làm trong bất kỳ ứng dụng nào khác Vừ̀a vặn trong trường hợp của Google, bạn phải sử dụng JDO (Hibernate, được cho là̀ một khung công tác ORM phổ biến cho Java, không làm việc với App Engine.)
JDO là khá đơn giản Bạn tạo các POJO — Plain Old Java Objects (các đối tượng thuần Java) (có thể các có mối quan hệ với các đối tượng Java khác) — mà bạn khai báo có khả năng lưu giữ lâu bền thông qua chú giải mức lớp
@PersistenceCapable Bạn xác định các thuộc tính nào của đối tượng được lưu giữ lâu bền qua các chú giải @Persistent Ví dụ, tôi muốn lưu trữ các sự kiện thi đấu
ba môn phối hợp (lúc này tôi sẽ tập trung vào sự kiện này mà không phải là nhiều kết quả khác có liên quan đến một cuộc thi đấu ba môn phối hợp) — có nghĩa là, một sự kiện có một tên (tên của cuộc thi đấu ba môn phối hợp), có thể là có một
mô tả (cuộc thi đấu ba môn phối hợp kiểu nào) và một ngày tháng Cho đến nay, JDO của tôi trông giống như Liệt kê 2:
Liệt kê 2 Một JDO của sự kiện thi đấu ba môn phối hợp đơn giản
import java.util.Date;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.IdentityType;
@PersistenceCapable(identityType = IdentityType.APPLICATION)
Trang 9public class Triathlon {
@Persistent
private Date date;
@Persistent
private String name;
@Persistent
private String description;
}
Lưu trữ lâu bền dữ liệu, bất kể cơ chế nằm dưới (đó là, cơ sở dữ liệu quan hệ hoặc
Big Table của Google) vẫn đòi hỏi khái niệm về khóa: một cách để bảo đảm tính
độc nhất của các khía cạnh dữ liệu khác nhau để tránh những xung đột dữ liệu Ví
dụ, trong trường hợp của một cuộc thi đấu ba môn phối hợp, khóa có thể là tên của cuộc thi đấu ba môn phối hợp này Nếu hai cuộc thi đấu ba môn phối hợp có cùng tên, thì khóa có thể là tổ hợp gồm tên và ngày tháng Bất kể bạn chọn để biểu diễn một khoá với App Engine của Google và JDO như thế nào, bạn phải chỉ định một khóa trong đối tượng JDO của bạn thông qua chú giải @PrimaryKey Bạn cũng có thể chọn các chiến lược để sinh ra một khóa như thế nào — hoặc do bạn làm hoặc
do cơ sở hạ tầng của Google Tôi sẽ dành việc này cho Google và làm cho nó đơn giản: khóa của đối tượng cuộc thi đấu ba môn phối hợp của tôi được biểu diễn như
là một đối tượng Long Java thông thường và tôi sẽ để cho Google chọn giá trị thực
tế bằng cách xác định một chiến lược giá trị Liệt kê 3 bổ sung thêm khóa chính:
Liệt kê 3 Thêm một khóa chính cho JDO của cuộc thi đấu ba môn phối hợp
Trang 10import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.IdentityType;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
@PersistenceCapable(identityType = IdentityType.APPLICATION) public class Triathlon {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Long id;
@Persistent
private Date date;
@Persistent