1 package org.apache.ojb.broker; 2 3 import org.apache.ojb.broker.query.Criteria; 4 import org.apache.ojb.broker.query.Query; 5 import org.apache.ojb.broker.query.QueryByCriteria; 6 import org.apache.ojb.broker.util.ObjectModificationDefaultImpl; 7 import org.apache.ojb.odmg.OJB; 8 import org.odmg.DList; 9 import org.odmg.Database; 10 import org.odmg.Implementation; 11 import org.odmg.OQLQuery; 12 import org.odmg.Transaction; 13 14 import java.util.Iterator ; 15 16 21 public class PerformanceTest3 22 { 23 private static String databaseNameFarAway = TestHelper.FAR_AWAY_DATABASE_NAME; 24 private static PBKey pbKey_FarAway = TestHelper.FAR_AWAY_KEY; 25 26 private static String databaseName = TestHelper.DEF_DATABASE_NAME; 27 private static PBKey pbKey = TestHelper.DEF_KEY; 28 29 private static int iterationsPerThread = 1000; 30 private static int concurrentThreads = 10; 31 private static int s_id = 10001; 33 private static int whichTest = 3; 34 private static boolean clientKeyGeneration = false; 35 36 42 private long[] times; 43 private int threadCount; 44 public ThreadGroup threadGroup = new ThreadGroup ("PerfTest"); 45 48 private Thread threads[] = null; 49 50 public PerformanceTest3() 51 { 52 this.threadCount = concurrentThreads; 53 } 54 55 public static void main(String [] args) 56 { 57 int loops = args.length > 4 ? Integer.parseInt(args[4]) : 1; 58 System.out.println("#######################################" + 59 "\n### Start stress test - do " + loops + " loop ###" + 60 "\n#######################################"); 61 for (int i = 0; i < loops; i++) 62 { 63 System.out.println("\n## perform loop " + (i + 1) + " ##"); 64 performTest(args); 65 } 66 System.exit(0); 67 } 68 69 private static void performTest(String [] args) 70 { 71 if (args.length > 0) 72 { 73 concurrentThreads = Integer.parseInt(args[0]); 74 } 75 if (args.length > 1) 76 { 77 iterationsPerThread = Integer.parseInt(args[1]); 78 } 79 if (args.length > 2) 80 { 81 clientKeyGeneration = Boolean.valueOf(args[2]).booleanValue(); 82 } 83 if (args.length > 3) 84 { 85 whichTest = Integer.parseInt(args[3]); 86 } 87 try 88 { 89 PerformanceTest3 test = new PerformanceTest3(); 90 int objectCountDefault = 0; 91 int objectCountDefaultAfter = 0; 92 int objectCountFarAway = 0; 93 int objectCountFarAwayAfter = 0; 94 95 if (whichTest == 1 || whichTest == 3) 96 { 97 test.init(); 98 objectCountDefault = test.getArticleCount(); 99 objectCountFarAway = test.getFarAwayCount(); 100 test.testMultithreaded_PB_api(); 101 102 System.err.println("Test-Info: Objects in default DB before PB test: " + objectCountDefault); 103 objectCountDefaultAfter = test.getArticleCount(); 104 System.err.println("Test-Info: Objects in default DB after PB test: " + objectCountDefaultAfter); 105 106 System.err.println("Test-Info: Objects in farAway_DB before PB test: " + objectCountFarAway); 107 objectCountFarAwayAfter = test.getFarAwayCount(); 108 System.err.println("Test-Info: Objects in farAway_DB after PB test: " + objectCountFarAwayAfter); 109 110 System.err.println("Test-Info: Stress test was successful? - " + 111 (objectCountDefault == objectCountDefaultAfter && (objectCountFarAway == objectCountFarAwayAfter)) + " -"); 112 } 113 114 115 if (whichTest == 2 || whichTest == 3) 116 { 117 test.init(); 118 objectCountDefault = test.getArticleCount(); 119 objectCountFarAway = test.getFarAwayCount(); 120 test.testMultithreaded_ODMG_api(); 121 122 System.err.println("Test-Info: Objects in default DB before ODMG test: " + objectCountDefault); 123 objectCountDefaultAfter = test.getArticleCount(); 124 System.err.println("Test-Info: Objects in default DB after ODMG test: " + objectCountDefaultAfter); 125 126 System.err.println("Test-Info: Objects in farAway_DB before ODMG test: " + objectCountFarAway); 127 objectCountFarAwayAfter = test.getFarAwayCount(); 128 System.err.println("Test-Info: Objects in farAway_DB after ODMG test: " + objectCountFarAwayAfter); 129 130 System.err.println("Test-Info: Stress test was successful? - " + 131 (objectCountDefault == objectCountDefaultAfter && (objectCountFarAway == objectCountFarAwayAfter)) + " -"); 132 } 133 } 134 catch (Exception e) 135 { 136 e.printStackTrace(); 137 } 138 } 139 140 143 protected void interruptThreads() 144 { 145 if (threads != null) 146 { 147 for (int i = 0; i < threads.length; i++) 148 { 149 threads[i].interrupt(); 150 } 151 } 152 System.err.println("## Test failed! ##"); 153 System.err.println("## Test failed! ##"); 154 } 155 156 159 protected void runTestClients(final TestClient[] runnables) 160 { 161 if (runnables == null) 162 { 163 throw new IllegalArgumentException ("runnables is null"); 164 } 165 threads = new Thread [runnables.length]; 166 for (int i = 0; i < threads.length; i++) 167 { 168 threads[i] = new Thread (runnables[i]); 169 } 170 for (int i = 0; i < threads.length; i++) 171 { 172 threads[i].start(); 173 } 174 try 175 { 176 for (int i = 0; i < threads.length; i++) 177 { 178 threads[i].join(); 179 } 180 } 181 catch (InterruptedException ignore) 182 { 183 System.out.println("Thread join interrupted."); 184 } 185 threads = null; 186 } 187 188 public synchronized void addTime(int position, long time) 189 { 190 times[position] = times[position] + time; 191 } 192 193 public void testMultithreaded_PB_api() 194 { 195 String sep = System.getProperty("line.separator"); 196 197 System.out.println(sep + sep + "++ Start thread generation for PB api test ++"); 198 System.out.println("Begin with performance test, " + concurrentThreads + 199 " concurrent threads, handle " + iterationsPerThread + " articles per thread"); 200 PerfomanceTestClientPB[] clientsPB = new PerfomanceTestClientPB[concurrentThreads]; 201 for (int i = 0; i < concurrentThreads; i++) 202 { 203 PerfomanceTestClientPB obj = new PerfomanceTestClientPB(this); 204 clientsPB[i] = obj; 205 } 206 System.out.println(""); 207 times[0] = System.currentTimeMillis(); 208 runTestClients(clientsPB); 209 times[0] = (long) (System.currentTimeMillis() - times[0]); 210 System.out.println(buildTestSummary("PB API")); 211 System.out.println("++ End of performance test PB api ++" + sep + sep); 212 } 213 214 public void testMultithreaded_ODMG_api() 215 { 216 String sep = System.getProperty("line.separator"); 217 System.out.println("++ Start thread generation for ODMG api test ++"); 218 System.out.println("Begin with performance test, " + concurrentThreads + 219 " concurrent threads, handle " + iterationsPerThread + " articles per thread"); 220 PerfomanceTestClientODMG[] clientsODMG = new PerfomanceTestClientODMG[concurrentThreads]; 221 for (int i = 0; i < concurrentThreads; i++) 222 { 223 PerfomanceTestClientODMG obj = new PerfomanceTestClientODMG(this); 224 clientsODMG[i] = obj; 225 } 226 System.out.println(""); 227 times[0] = System.currentTimeMillis(); 228 runTestClients(clientsODMG); 229 times[0] = (long) (System.currentTimeMillis() - times[0]); 230 System.out.println(buildTestSummary("ODMG")); 231 System.out.println("++ End of performance test ODMG api ++" + sep); 232 } 233 234 private String buildTestSummary(String key) 235 { 236 String sep = System.getProperty("line.separator"); 237 StringBuffer buf = new StringBuffer (); 238 buf.append(sep); 239 buf.append("----------------------------------------------------"); 240 buf.append(sep); 241 buf.append("TEST SUMMARY - " + key); 242 buf.append(sep); 243 buf.append(concurrentThreads + " concurrent threads, handle " + iterationsPerThread + " articles per thread"); 244 buf.append(sep); 245 buf.append("Test period: " + (double) (((double) times[0]) / 1000) + " [sec]"); 246 buf.append(sep); 247 buf.append("Inserting period: " + (times[1] / (concurrentThreads)) + " [msec]"); 248 buf.append(sep); 249 buf.append("Fetching period: " + (times[2] / (concurrentThreads)) + " [msec]"); 250 buf.append(sep); 251 buf.append("Deleting period: " + (times[3] / (concurrentThreads)) + " [msec]"); 252 buf.append(sep); 253 buf.append("----------------------------------------------------"); 254 255 return buf.toString(); 256 } 257 258 259 abstract class TestClient implements Runnable 260 { 261 262 } 263 264 268 271 class PerfomanceTestClientODMG extends TestClient 272 { 273 private PerformanceArticle[] arr; 274 private FarAwayClass[] arrFarAway; 275 private Implementation ojb; 276 private static final String PRE_NAME = "A_"; 277 private String threadName; 278 private PerformanceTest3 test; 279 280 public PerfomanceTestClientODMG(PerformanceTest3 test) 281 { 282 this.test = test; 283 } 284 285 public void run() 286 { 287 ojb = OJB.getInstance(); 288 threadName = Thread.currentThread().getName(); 289 arr = new PerformanceArticle[iterationsPerThread]; 290 for (int i = 0; i < iterationsPerThread; i++) 291 { 292 PerformanceArticle a = createArticle(i, threadName); 293 arr[i] = a; 294 } 295 296 arrFarAway = new FarAwayClass[iterationsPerThread]; 297 for (int i = 0; i < iterationsPerThread; i++) 298 { 299 FarAwayClass a = createFarAwayObject(i, threadName); 300 arrFarAway[i] = a; 301 } 302 303 try 305 { 306 insertNewArticles(); 307 readArticlesByCursor(); 308 deleteArticles(); 309 insertNewFarAways(); 310 readFarAwaysByCursor(); 311 deleteFarAways(); 312 } 313 catch (Throwable e) 314 { 315 e.printStackTrace(); 316 System.err.println("Error in client " + this); 317 test.interruptThreads(); 318 } 319 } 320 321 325 private PerformanceArticle createArticle(int id, String name) 326 { 327 PerformanceArticle a = new PerformanceArticle(); 328 if (clientKeyGeneration) a.setArticleId(getId()); 329 a.setArticleName(PRE_NAME + name); 330 a.setMinimumStock(100); 331 a.setOrderedUnits(17); 332 a.setPrice(0.45); 333 a.setProductGroupId(1); 334 a.setStock(234); 335 a.setSupplierId(4); 336 a.setUnit("bottle"); 337 return a; 338 } 339 340 private FarAwayClass createFarAwayObject(int i, String name) 341 { 342 FarAwayClass fa = new FarAwayClass(); 343 if (clientKeyGeneration) fa.setId(getId()); 344 fa.setName(PRE_NAME + name); 345 fa.setDescription("so far away from " + i); 346 return fa; 347 } 348 349 protected void deleteArticles() throws Exception 350 { 351 long start = System.currentTimeMillis(); 352 Database db = ojb.newDatabase(); 353 db.open(databaseName, Database.OPEN_READ_WRITE); 354 for (int i = 0; i < arr.length; i++) 355 { 356 Transaction tx = ojb.newTransaction(); 357 tx.begin(); 358 db.deletePersistent(arr[i]); 359 tx.commit(); 360 } 361 db.close(); 362 long stop = System.currentTimeMillis(); 363 times[3] = times[3] + (stop - start); 364 } 365 366 protected void deleteFarAways() throws Exception 367 { 368 long start = System.currentTimeMillis(); 369 Database db = ojb.newDatabase(); 370 db.open(databaseNameFarAway, Database.OPEN_READ_WRITE); 371 for (int i = 0; i < arr.length; i++) 372 { 373 Transaction tx = ojb.newTransaction(); 374 tx.begin(); 375 db.deletePersistent(arrFarAway[i]); 376 tx.commit(); 377 } 378 db.close(); 379 long stop = System.currentTimeMillis(); 380 times[3] = times[3] + (stop - start); 381 } 382 383 protected void insertNewArticles() throws Exception 384 { 385 long start = System.currentTimeMillis(); 386 Database db = ojb.newDatabase(); 387 db.open(databaseName, Database.OPEN_READ_WRITE); 388 for (int i = 0; i < arr.length; i++) 389 { 390 Transaction tx = ojb.newTransaction(); 391 tx.begin(); 392 tx.lock(arr[i], Transaction.WRITE); 393 tx.commit(); 394 } 395 db.close(); 396 long stop = System.currentTimeMillis(); 397 times[1] = times[1] + (stop - start); 398 } 399 400 protected void insertNewFarAways() throws Exception 401 { 402 long start = System.currentTimeMillis(); 403 Database db = ojb.newDatabase(); 404 db.open(databaseNameFarAway, Database.OPEN_READ_WRITE); 405 for (int i = 0; i < arr.length; i++) 406 { 407 Transaction tx = ojb.newTransaction(); 408 tx.begin(); 409 tx.lock(arrFarAway[i], Transaction.WRITE); 410 tx.commit(); 411 } 412 db.close(); 413 long stop = System.currentTimeMillis(); 414 times[1] = times[1] + (stop - start); 415 } 416 417 protected void readArticlesByCursor() throws Exception 418 { 419 long start = System.currentTimeMillis(); 420 int artId = arr[0].articleId; 421 422 Database db = ojb.newDatabase(); 423 db.open(databaseName, Database.OPEN_READ_WRITE); 424 425 Transaction tx = ojb.newTransaction(); 426 tx.begin(); 427 OQLQuery query = ojb.newOQLQuery(); 428 String sql = "select allArticles from " + PerformanceArticle.class.getName() + 429 " where articleName = \"" + PRE_NAME + threadName + "\""; 430 query.create(sql); 431 DList allProducts = (DList) query.execute(); 432 tx.commit(); 433 434 Iterator iter = allProducts.iterator(); 435 int fetchCount = 0; 436 while (iter.hasNext()) 437 { 438 fetchCount++; 439 PerformanceArticle a = (PerformanceArticle) iter.next(); 440 } 441 db.close(); 442 long stop = System.currentTimeMillis(); 443 times[2] = times[2] + (stop - start); 444 } 445 446 protected void readFarAwaysByCursor() throws Exception 447 { 448 long start = System.currentTimeMillis(); 449 int farAway_id = arrFarAway[0].getId(); 450 451 Database db = ojb.newDatabase(); 452 db.open(databaseNameFarAway, Database.OPEN_READ_WRITE); 453 Transaction tx = ojb.newTransaction(); 454 tx.begin(); 455 OQLQuery query = ojb.newOQLQuery(); 456 String sql = "select allFarAways from " + FarAwayClass.class.getName() + 457 " where name = \"" + PRE_NAME + threadName + "\""; 458 query.create(sql); 459 DList allFarAways = (DList) query.execute(); 460 tx.commit(); 461 Iterator iter = allFarAways.iterator(); 462 int fetchCount = 0; 463 while (iter.hasNext()) 464 { 465 fetchCount++; 466 FarAwayClass a = (FarAwayClass) iter.next(); 467 } 468 db.close(); 469 long stop = System.currentTimeMillis(); 470 times[2] = times[2] + (stop - start); 471 } 472 } 473 474 480 class PerfomanceTestClientPB extends TestClient 481 { 482 private PerformanceArticle[] arr; 483 private FarAwayClass[] arrFarAway; 484 private Implementation ojb; 485 private PerformanceTest3 test; 486 487 public PerfomanceTestClientPB(PerformanceTest3 test) 488 { 489 this.test = test; 490 ojb = OJB.getInstance(); 491 arr = new PerformanceArticle[iterationsPerThread]; 492 for (int i = 0; i < iterationsPerThread; i++) 493 { 494 PerformanceArticle a = createArticle(i); 495 arr[i] = a; 496 } 497 498 arrFarAway = new FarAwayClass[iterationsPerThread]; 499 for (int i = 0; i < iterationsPerThread; i++) 500 { 501 FarAwayClass a = createFarAwayObject(i); 502 arrFarAway[i] = a; 503 } 504 } 506 507 public void run() 508 { 509 try 511 { 512 insertNewFarAways(); 513 insertNewArticles(); 514 readArticlesByCursor(); 515 readFarAwaysByCursor(); 516 deleteArticles(); 517 deleteFarAways(); 518 } 519 catch (Throwable e) 520 { 521 e.printStackTrace(); 522 System.err.println("Error in client " + this); 523 test.interruptThreads(); 524 } 525 } 526 527 531 private PerformanceArticle createArticle(int id) 532 { 533 PerformanceArticle a = new PerformanceArticle(); 534 if (clientKeyGeneration) a.setArticleId(getId()); 535 a.setArticleName("New Performance Article " + id); 536 a.setMinimumStock(100); 537 a.setOrderedUnits(17); 538 a.setPrice(0.45); 539 a.setProductGroupId(1); 540 a.setStock(234); 541 a.setSupplierId(4); 542 a.setUnit("bottle"); 543 return a; 544 } 545 546 private FarAwayClass createFarAwayObject(int i) 547 { 548 FarAwayClass fa = new FarAwayClass(); 549 if (clientKeyGeneration) fa.setId(getId()); 550 fa.setName("away from " + i); 551 fa.setDescription("so far away from " + i); 552 return fa; 553 } 554 555 protected void deleteArticles() throws Exception 556 { 557 long start = System.currentTimeMillis(); 558 559 for (int i = 0; i < arr.length; i++) 560 { 561 PersistenceBroker broker = null; 562 try 563 { 564 broker = PersistenceBrokerFactory.defaultPersistenceBroker(); 565 broker.beginTransaction(); 566 broker.delete(arr[i]); 567 broker.commitTransaction(); 568 } 569 finally 570 { 571 if (broker != null) broker.close(); 572 } 573 } 574 575 long stop = System.currentTimeMillis(); 576 times[3] = times[3] + (stop - start); 577 } 578 579 protected void deleteFarAways() throws Exception 580 { 581 long start = System.currentTimeMillis(); 582 583 for (int i = 0; i < arr.length; i++) 584 { 585 PersistenceBroker broker = null; 586 try 587 { 588 broker = PersistenceBrokerFactory.createPersistenceBroker(pbKey_FarAway); 589 broker.beginTransaction(); 590 broker.delete(arrFarAway[i]); 591 broker.commitTransaction(); 592 } 593 finally 594 { 595 if (broker != null) broker.close(); 596 } 597 } 598 599 long stop = System.currentTimeMillis(); 600 times[3] = times[3] + (stop - start); 601 } 602 603 protected void insertNewArticles() throws Exception 604 { 605 606 ObjectModificationDefaultImpl needsInsert = new ObjectModificationDefaultImpl(); 607 needsInsert.setNeedsInsert(true); 608 609 long start = System.currentTimeMillis(); 610 611 for (int i = 0; i < arr.length; i++) 612 { 613 PersistenceBroker broker = null; 614 try 615 { 616 broker = PersistenceBrokerFactory.defaultPersistenceBroker(); 617 broker.beginTransaction(); 618 broker.store(arr[i], needsInsert); 619 broker.commitTransaction(); 620 } 621 finally 622 { 623 if (broker != null) broker.close(); 624 } 625 626 } 627 628 long stop = System.currentTimeMillis(); 629 times[1] = times[1] + (stop - start); 630 } 631 632 protected void insertNewFarAways() throws Exception 633 { 634 635 ObjectModificationDefaultImpl needsInsert = new ObjectModificationDefaultImpl(); 636 needsInsert.setNeedsInsert(true); 637 638 long start = System.currentTimeMillis(); 639 640 for (int i = 0; i < arr.length; i++) 641 { 642 PersistenceBroker broker = null; 643 try 644 { 645 broker = PersistenceBrokerFactory.createPersistenceBroker(pbKey_FarAway); 646 broker.beginTransaction(); 647 broker.store(arrFarAway[i], needsInsert); 648 broker.commitTransaction(); 649 } 650 finally 651 { 652 if (broker != null) broker.close(); 653 } 654 655 } 656 657 long stop = System.currentTimeMillis(); 658 times[1] = times[1] + (stop - start); 659 } 660 661 protected void readArticlesByCursor() throws Exception 662 { 663 long start = System.currentTimeMillis(); 664 int artId = arr[0].articleId; 665 666 Criteria c = new Criteria(); 667 c.addBetween("articleId", new Integer (artId), new Integer (artId + iterationsPerThread)); 668 Query q = new QueryByCriteria(PerformanceArticle.class, c); 669 670 PersistenceBroker broker = null; 671 try 672 { 673 broker = PersistenceBrokerFactory.defaultPersistenceBroker(); 674 Iterator iter = broker.getIteratorByQuery(q); 675 int fetchCount = 0; 676 while (iter.hasNext()) 677 { 678 fetchCount++; 679 PerformanceArticle a = (PerformanceArticle) iter.next(); 680 } 681 } 682 finally 683 { 684 if (broker != null) broker.close(); 685 } 686 687 688 long stop = System.currentTimeMillis(); 689 times[2] = times[2] + (stop - start); 690 } 691 692 protected void readFarAwaysByCursor() throws Exception 693 { 694 long start = System.currentTimeMillis(); 695 int farAway_id = arrFarAway[0].getId(); 696 697 Criteria c = new Criteria(); 698 c.addBetween("id", new Integer (farAway_id), new Integer (farAway_id + iterationsPerThread)); 699 Query q = new QueryByCriteria(FarAwayClass.class, c); 700 701 PersistenceBroker broker = null; 702 try 703 { 704 broker = PersistenceBrokerFactory.createPersistenceBroker(pbKey_FarAway); 705 Iterator iter = broker.getIteratorByQuery(q); 706 int fetchCount = 0; 707 while (iter.hasNext()) 708 { 709 fetchCount++; 710 FarAwayClass a = (FarAwayClass) iter.next(); 711 } 712 } 713 finally 714 { 715 if (broker != null) broker.close(); 716 } 717 718 719 long stop = System.currentTimeMillis(); 720 times[2] = times[2] + (stop - start); 721 } 722 } 723 724 728 729 732 public synchronized static int getId() 733 { 734 return ++s_id; 735 } 736 737 public int getArticleCount() 738 { 739 Criteria c = new Criteria(); 740 Query q = new QueryByCriteria(PerformanceArticle.class, c); 741 int count = 0; 742 try 743 { 744 PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker(); 745 broker.clearCache(); 746 count = broker.getCount(q); 747 broker.close(); 748 } 749 catch (Exception e) 750 { 751 e.printStackTrace(); 752 } 753 return count; 754 } 755 756 public int getFarAwayCount() 757 { 758 Criteria c = new Criteria(); 759 Query q = new QueryByCriteria(FarAwayClass.class, c); 760 int count = 0; 761 try 762 { 763 PersistenceBroker broker = PersistenceBrokerFactory.createPersistenceBroker(pbKey_FarAway); 764 broker.clearCache(); 765 count = broker.getCount(q); 766 broker.close(); 767 } 768 catch (Exception e) 769 { 770 e.printStackTrace(); 771 } 772 return count; 773 } 774 775 778 public void init() throws Exception 779 { 780 times = new long[4]; 782 threadCount = concurrentThreads; 783 784 if (whichTest == 1 || whichTest == 3) 785 { 786 PerformanceArticle art = createArticle(1000); 788 PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker(); 789 broker.beginTransaction(); 790 broker.store(art); 791 broker.commitTransaction(); 792 793 broker.beginTransaction(); 794 broker.delete(art); 795 broker.commitTransaction(); 796 broker.close(); 797 } 798 799 if (whichTest == 2 || whichTest == 3) 800 { 801 PerformanceArticle art2 = createArticle(1001); 803 Implementation ojb = OJB.getInstance(); 804 Database db = ojb.newDatabase(); 805 db.open(databaseName, Database.OPEN_READ_WRITE); 806 Transaction tx = ojb.newTransaction(); 807 tx.begin(); 808 tx.lock(art2, Transaction.WRITE); 809 tx.commit(); 810 811 tx.begin(); 812 db.deletePersistent(art2); 813 tx.commit(); 814 db.close(); 815 } 817 } 818 819 823 private PerformanceArticle createArticle(int id) 824 { 825 PerformanceArticle a = new PerformanceArticle(); 826 if (clientKeyGeneration) a.setArticleId(getId()); 827 a.setArticleName("New Performance Article " + id); 828 a.setMinimumStock(100); 829 a.setOrderedUnits(17); 830 a.setPrice(0.45); 831 a.setProductGroupId(1); 832 a.setStock(234); 833 a.setSupplierId(4); 834 a.setUnit("bottle"); 835 return a; 836 } 837 } 838 | Popular Tags |