ssh注解中主键生成策略无效

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ssh注解中主键生成策略无效相关的知识,希望对你有一定的参考价值。

@Id
@GeneratedValue(generator="UserInfoId")
@GenericGenerator(name="UserInfoId", strategy="assigned")
@Column(name="id",unique=true,nullable=false)
public String getId()
return id;

public void setId(String id)
this.id = id;

entity类是这样写的,在注册或者插入数据时,saveorupdate()不管如何就是update,页面错误:org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1都没有要更新的数据更新肯定错误啊,我要执行的是插入,不知道是不是注解写的主键生成策略有什么地方不对或写漏了,我是把原项目写成基于全注解的,后来就各种问题,求大神帮忙

@GeneratedValue(generator="UserInfoId")这行不对

可用的值如下:
increment
用于为long, short或者int类型生成 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。
identity
对DB2,mysql, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long, short 或者int类型的。
sequence
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。
hilo
使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是 hibernate_unique_key 和next_hi)作为高位值的来源。 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
seqhilo
使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。
uuid
用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
guid
在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。
native
根据底层数据库的能力选择identity, sequence 或者hilo中的一个。
assigned
让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定时的默认生成策略。
select
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
foreign
使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。
sequence-identity
一种特别的序列生成策略,使用数据库序列来生成实际值,但将它和JDBC3的getGeneratedKeys结合在一起,使得在插入语句执行的时候就返回生成的值。目前为止只有面向JDK
1.4的Oracle 10g驱动支持这一策略。注意,因为Oracle驱动程序的一个bug,这些插入语句的注释被关闭了。(原文:Note comments on these insert statements are disabled due to a bug in the Oracle drivers.)追问

哥们,别做复制党

追答

你开始问的问题就那个,查帮助就能搞定,后来改的这个问题。。。其实是另一回事了。
在save方法里就是执行插入,但是 saveOrUpdate方法里执行的就不一定了。需要你的实体对象加上equals和hashCode方法,区别两个对象的方式改为ID只要ID一样,对象就一样。
因为你在对象瞬态的时候,变为持久态,可能会有ID一样的两个对象出现,第一次读取id=1的对象,和第二次读取id=1的对象,关闭session后,对象都已经游离。没办法确定是一个,所以需要重设equals和hashcode两个方法。
另外你的ID必须是自己指定的。因为你设置了assigned,所以不能指定数据库为你生成,你得自己加上。如果不加ID,hibernate当然不能向表插入一个没有主键的数据。

追问

其实我的问题是程序帮我更新了数据库里一条没有id的数据,我要执行的是插入新数据的操作,saveorupdate却执行了update,最后当然报错了,至于assigned怎么用我当然知道

追答

那真是对不起了,早知道你懂的这么多,我就不说话了。百度知道应该把你懂的问题都隐藏了。

追问

哥们,我的项目在没有写成基于注解前是一切运行正常的,写成注解后就这样了,主键生成策略原来是assigned的,改成注解后依然是assigned,不知道是我没看懂你的回答还是我说得不够清楚

参考技术A assigned这是自己分配主键,不会自动生成的。
需要在保存的时候自己设置一个主键。
参考技术B @GeneratedValue(strategy=GenerationType.IDENTITY)ID自增追问

数据库id是varchar类型怎么自增

追答

哦,没看到类型是String的

SSH注解整合

首先是实体类中的注解:

@Entity
@Table(name = "Stock")
public class Stock {
    @Id //标识实体中ID和底层数据表的主键统一
    @GeneratedValue(strategy = GenerationType.IDENTITY)   //主键生成策略:mysql 底层自动autoincreament
    private int sid;     //股票编号
    private String sname;//股票名称   YYM教育
    @Column(name="scount")
    private int scount;  //股数

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public int getScount() {
        return scount;
    }

    public void setScount(int scount) {
        this.scount = scount;
    }
}

然后就是dao层中注解:

@Repository("stockDAO")
public class StockDAOImpl implements IStockDAO {
    //dao植入SessionFactory变量  重量级
    //使用自动装配让SessionFactory
    @Autowired
    private SessionFactory sessionFactory;
    public int addStock(Stock stock) {
        System.out.println(sessionFactory+"========================");
        Session session = sessionFactory.getCurrentSession();
        Serializable count=session.save(stock);
        Integer cc=(Integer)count;
        return cc.intValue();
    }

}

之后就是service中的注解:

@Service("stockService")
public class StockServiceImpl implements IStockService {
    //植入dao的接口变量
    @Resource(name = "stockDAO")
    private IStockDAO dao;
    @Transactional
    public int saveStock(Stock stock) {
        return dao.addStock(stock);
    }
}

然后就是action连接service

@Controller
@Scope(value = "prototype")
@ParentPackage("struts-default")
@Namespace("/")
public class StockAction extends ActionSupport implements ModelDriven<Stock> {
   //Entity变量
    private Stock stock;
    @Resource(name = "stockService")
    private IStockService service;

    public StockAction(){
        stock=new Stock();
    }
    @Action(value = "addStock",results = {@Result( name = "success",location = "/success.jsp"),@Result(name="input",location = "/add.jsp")})
    public String execute() throws Exception {
        int count = service.saveStock(stock);
        if (count>0) {
            return SUCCESS;
        }else {
            return INPUT;
        }
    }
    public Stock getModel() {
        return stock;
    }
}
 <!--开启包扫描器-->
    <context:component-scan base-package="cn.wwy"></context:component-scan>
    <!--1.Datasource-->
    <!--1.配置数据源c3p0-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClassName}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
    </bean>

    <!--jdbc.properties-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!--2.SessionFactory         类:Local-->
      <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
          <property name="hibernateProperties">
              <props>
                   <!--hibernate.xxxxxx必须以hibernate-->
                  <prop key="hibernate.show_sql">true</prop>
                  <prop key="hibernate.format_sql">true</prop>
                  <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                  <!--with current thread bind session-->
                  <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</prop>
              </props>
          </property>
          <property name="packagesToScan" value="cn.wwy.beans"></property>
    </bean>

    <!--5.事务管理器-->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <!--6.事务-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

pom.xml文件

 <!--jta的jar包-->
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
    </dependency>

    <!--mysql数据库驱动-->
    <dependency>
      <groupId>org.wisdom-framework</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.34_1</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.0.6.Final</version>
    </dependency>

    <!--以上是HIbernate的jar包配置-->

    <!--下面是Spring相关的jar包配置-->
    <!--c3p0-->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>

    <!--AOP的相关jar-->
    <dependency>
      <groupId> org.aspectj</groupId >
      <artifactId> aspectjweaver</artifactId >
      <version> 1.8.7</version >
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.2.0.RELEASE</version>
    </dependency>

    <!--Spring-ORM-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version> 4.2.2.RELEASE</version>
    </dependency>

    <!--以下是Struts2的jar包-->
    <!--1.获取ServletAPI-->
    <dependency>
      <groupId>javaee</groupId>
      <artifactId>javaee-api</artifactId>
      <version>5</version>
    </dependency>

    <dependency>
      <groupId>org.apache.struts</groupId>
      <artifactId>struts2-core</artifactId>
      <version>2.3.4.1</version>
    </dependency>

    <dependency>
      <groupId>org.apache.struts.xwork</groupId>
      <artifactId>xwork-core</artifactId>
      <version>2.3.4.1</version>
    </dependency>

    <!--Spring-web-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.1.8.RELEASE</version>
    </dependency>

    <!--Struts整合Spring的jar包-->
    <dependency>
      <groupId>org.apache.struts</groupId>
      <artifactId>struts2-spring-plugin</artifactId>
      <version>2.3.4.1</version>
    </dependency>

    <dependency>
      <groupId>org.apache.struts</groupId>
      <artifactId>struts2-convention-plugin</artifactId>
      <version>2.3.4.1</version>
    </dependency>

  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>
  </build>
</project>

 

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

 

以上是关于ssh注解中主键生成策略无效的主要内容,如果未能解决你的问题,请参考以下文章

JPA注解主键生成策略-UUID

在java中 主键生成策略(hibernate)都是指的是id的吗

JPA注解

Hibernate——主键生成策略CRUD 基础API区别的总结 和 注解的使用

SSH注解整合

Hibernate 注解序列生成主键执行完select seq_t_user.nextval后不执行insert等语句导致 执行save()或update()方法无效