2011-10-13 39 views
5

Daha önce hiçbir zaman Java enum sınıflarını sabit değerler için kullanmamıştım, geçmişte genellikle "herkese açık final" yaklaşımını kullandım. Şimdi bir enum kullanmaya başladım ve enum adından farklı bir değer döndürmek için toString() yöntemini geçersiz kılıyorum.Java enum'u geçersiz kılar toString()

Bazı JPA kodlarım var, bunlardan biri adlandırılmış parametrelerle bir TypedQuery oluşturuyorum, bunlardan biri enum değerinin String temsilidir. Status.ACTIVE kullanarak yalnızca parametreyi ayarlarsanız, uygun "A" değerini alırım, ancak tür aslında aslında String'den ziyade bir durum olduğu için bir istisna atılır. Sadece toString() yöntemini açıkça çağırırsam çalışır. Sadece sınıf türü ne olursa olsun toString() yöntemini geçersiz kılmanın bir String türünün döndürülmesini sağlayacağını düşündüm.

TypedQuery<MechanicTimeEvent> query = entityManager().createQuery("SELECT o FROM MechanicTimeEvent o WHERE o.id.mechanicNumber = :mechanicNumber AND o.id.status = :status", MechanicTimeEvent.class); 
    query.setParameter("mechanicNumber", mechanicNumber); 
    query.setParameter("status", Status.ACTIVE.toString()); 
+0

Bu alanın eşlemesini soruya ekleyebilir miyim? – Augusto

+1

Yazmak için daha özlü bir yol arıyorsanız, 'query.setParameter (" durum ", Status.ACTIVE +" ");' çalışır. – Eric

+1

: "Durum" türündeki "Durum" türündeki alan mı ve @ @ Enüsteli (EnumType.STRING) 'ile açıklamalı mı? Öyleyse, enumları sorgularda kullanabilmeniz gerekir. –

cevap

3

MechanicTimeEvent Bean'in status alanı bir enum tür mü? Değilse, bunu Status numaralandırma numarasına değiştirmenizi öneririm.

Sen Üstelik ben senin enum değeri kısmını kaldırmak için öneririm @Enumerated(EnumType.STRING)

ile açıklama ve gibi isimler kullanın: loft yazdığı gibi

public enum Status { 
    ACTIVE, 
    PENDING, 
    FINISHED; 
} 
+0

Enum tipi değildi, bu yüzden Durumu yazarak değiştirdim ve önerdiğiniz ek açıklamaları ekledim. Bence bu hile yaptı. Garip bir şey, eğer sorgu ile herhangi bir kayıt bulunamazsa, o zaman iyi çalışıyor, ancak bir kayıt bulursa, OpenJPA bir ArgumentException atar ve bana sorgumun sözdizimini kontrol etmem gerektiğini söyler. –

+0

Dizge yerine enum değerini kullandınız mı ?: ie query.setParameter ("status", Status.ACTIVE) – lauwie

+0

Aslında, veritabanı yalnızca değerleri depoladığı için, yani: A, P veya F, select ifadesi oluştururken, OpenJPA sorgudan döndürülen değeri A enum'un valueOf yöntemine geçirir. Enumda A'yı bulamadığı için istisnayı atar. ValueOf yöntemi son, bu yüzden geçersiz kılamıyorum. –

0

Bu veya sadece değer için bir alıcı uygulamak: Bu TypedQuery olan

public enum Status { 
    ACTIVE ("A"), 
    PENDING ("P"), 
    FINISHED ("F"); 

    private final String value; 

    Status(String value) { 
     this.value = value; 
    } 

    public String toString() { 
     return value; 
    } 
}; 

:

Bu

enum olan

public String getValue() 

Ve diyoruz kodunuzda:

query.setParameter("status", Status.ACTIVE.getValue()); 
0

toString, ObjectStream.println (System.out.println unutmayın) gibi bazı yöntemlerle açıkça çağrılan veya + işlecini kullanarak birleştirme sırasında göz önünde bulundurulan Object'te sıradan bir yöntemdir. Her yöntemin bu davranışı uygulaması gerekmez.

Sana Arkanı enum haritalayan başka bir yol yapmalıyım, getValue gibi daha açıklayıcı bir yöntem adını kullanmak ve Sorunuzu doğru anlamak geçersiz kılma toString

3

açıkça yerine diyoruz öneririm. Bu şekilde, durumlar devlet olarak depolanır ve JPA, enum'u A, P, F) adında işler.

public enum Status { 
    A("ACTIVE"), 
    P("PENDING"), 
    F("FINISHED"); 

Bu şekilde, toString() yöntemini JPA'ya çağırmadan Durumu geçebilirsiniz. ENUM üzerindeki .name() yöntemi, kalıcılık için durum kodunu almak üzere otomatik olarak çağrılır.

+1

Alan adlarını bir harfle kesmemelisiniz, çünkü bu sizin veritabanınız/kullandığınız her şeydir. Sadece .name() 'yi geçersiz kılmıyor musunuz? – Eric

+2

Enum.name() yöntemi son olduğundan geçersiz kılınamaz. –

+2

Bunu yapmamın amacı, başka biri kodu okursa, Status.ACTIVE Status.A'dan daha açık. –

-1
java.lang.Enum said clearly: 
/** 
* Returns the name of this enum constant, exactly as declared in its 
* enum declaration. 
* 
* <b>Most programmers should use the {@link #toString} method in 
* preference to this one, as the toString method may return 
* a more user-friendly name.</b> This method is designed primarily for 
* use in specialized situations where correctness depends on getting the 
* exact name, which will not vary from release to release. 
* 
* @return the name of this enum constant 
*/ 
public final String name() 

, ismi almak için "isim" yöntemini kullanabilirsiniz. ayrıca toString() yöntemini de kullanabilirsiniz. Tabii ki bu enum sabitinin adı sadece

.

5
public enum Status { 
    ACTIVE, 
    PENDING, 
    FINISHED; 

    @Override 
    public String toString() { 
     String name = ""; 
     switch (ordinal()) { 
     case 0: 
      name = "A"; 
      break; 
     case 1: 
      name = "P"; 
      break; 
     case 2: 
      name = "F"; 
      break; 
     default: 
      name = ""; 
      break; 
     } 
     return name; 
    } 
}; 
+6

Bu toString() uygulaması, özellikle enum adlarının gelecekte ekleneceği durumlarda çok fazla bakım gerektirir. instanciation üzerinde bir dize değeri atamak ve bunun yerine bunu döndürmek en iyisidir. – initialZero

+0

... Soru çözümü sağladığı gibi. Bu kod daha okunabilir ve "Dize eşleştirmesi" ("AKTİF" ("A") ") arasındaki konum da, yazım hatasıyla kod çalıştırmayı engeller (örneğin: case 3: name =" E "' yerine case 2: name = "F" '). Ayrıca, anahtar varsayılan değeri anlamsızdır. –

İlgili konular