Hibernate Space is not allowed after parameter prefix ':'

本文介绍了一种在使用Hibernate框架进行数据库操作时遇到的space is not allowed after parameter prefix ':'错误的解决方法,通过分析错误原因及修改SQL语句格式,确保了数据库更新操作的正确执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、数据库表的设计如下:

DROP TABLE IF EXISTS `crawler_device`;
CREATE TABLE `crawler_device` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `vendor_name` varchar(32) NOT NULL COMMENT '终端制造商名称',
  `vendor_url` varchar(128) NOT NULL COMMENT '终端制造商页面',
  `device_name` varchar(48) NOT NULL COMMENT '终端型号名称',
  `device_format_name` varchar(48) DEFAULT NULL COMMENT '终端型号格式化名称',
  `device_url` varchar(128) NOT NULL COMMENT '终端制造商页面',
  `os_name` varchar(48) DEFAULT NULL COMMENT '操作系统名称',
  `os_format_name` varchar(48) DEFAULT NULL COMMENT '操作系统格式化名称',
  `price` varchar(32) NOT NULL COMMENT '价格或产品状态',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `device_url` (`device_url`)
) ENGINE=InnoDB AUTO_INCREMENT=11814 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

2、利用hibernate 对数据库进行操作;

按照ID和unique Key对数据进行更新;

package com.everdata.crawlers.main;

import java.io.IOException;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Property;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.everdata.common.constant.CommonConstants;
import com.everdata.crawlers.dao.impl.CrawlerDeviceDaoImpl;
import com.everdata.crawlers.dao.impl.CrawlerVendorDaoImpl;
import com.everdata.crawlers.domain.CrawlerDevice;
import com.everdata.crawlers.domain.CrawlerVendor;
import com.everdata.crawlers.format.DeviceFormat;
import com.everdata.crawlers.vo.DeviceVo;
import com.everdata.crawlers.vo.VendorVo;

	public void crawler() {
		//获取所有的品牌;
		List<VendorVo> list = getVendors();
		CrawlerVendorDaoImpl manufDao = new CrawlerVendorDaoImpl();
		CrawlerDeviceDaoImpl deviceDao = new CrawlerDeviceDaoImpl();
		for (VendorVo vo : list) {
			//DetachedCriteria:离线创建criteria 且好构建查询条件;DetachedCriteria类允许你在Hibernate的Session范围外创建一个查询,
			//然后使用任意一个Session环境去执行它;
			DetachedCriteria dc_manu = DetachedCriteria.forClass(CrawlerVendor.class);
			//如果为空则保存到数据库;
			String url = vo.getUrl();
			DetachedCriteria dc = dc_manu.add(Property.forName("vendorUrl").eq(url));
			List<CrawlerVendor> fdc = manufDao.findByDetachedCriteria(dc);
			if (fdc.isEmpty()) {
				System.out.println(vo);
				manufDao.save(toCrawlerVendor(vo));
			} else {
				logger.info(vo.getVendor() + " :this vendor is exist!");
			}
			//获取每个品牌对应的型号;
			List<DeviceVo> devices = getDevices(vo);
			for (DeviceVo device : devices) {
				DetachedCriteria dc_device = DetachedCriteria.forClass(CrawlerDevice.class);
				List<CrawlerDevice> fd = deviceDao.findByDetachedCriteria(dc_device.add(Property.forName("deviceUrl").eq(device.getUrl())));
				CrawlerDevice result = toCrawlerDevice(device);
				if (fd.isEmpty()) {
					deviceDao.save(result);
					logger.info(result+ "saved");
				} else {
					String sql="update crawler_device set vendor_name=\""+result.getVendorName()
							+", vendor_url="+result.getVendorUrl()
							+", device_name="+result.getDeviceName()
							+", device_format_name="+result.getDeviceFormatName()
							+", os_name="+result.getOsName()
							+", os_format_name="+result.getOsFormatName()
							+", price="+result.getPrice()
							+", update_time="+result.getUpdateTime()
							+" where device_url="+result.getDeviceUrl()
							+" and id="+fd.get(0).getId();
					deviceDao.executeNativeSql(sql);
					logger.info(result + " updated!");
				}
			}
		}
	}

3、报错具体如下:

Space is not allowed after parameter prefix ':'

4、解决方式

4.1 网上有很多的解决方式都是在“:”前加转义字符 \\;

4.2 我查看数据表的设计,所有的字段都设计为varchar;且报错的字段只与和URL相关的字段有关系;查看其执行过程:

 update
        crawler_device 
    set
        vendor_name=魅蓝,
        vendor_url=http://product.cnmo.com/pro_sub_manu/sub_57_manu_32909_1_2.shtml,
        device_name=魅蓝U10(16GB),
        device_format_name=魅蓝U10,
        os_name=YunOS,
        os_format_name=其他,
        price=停产,
        update_time=2018-08-08 
    where
        device_url=http://product.cnmo.com/cell_phone/index1623436.shtml 
        and id=11111

发现很多字段应该为varchar 但是没有单引号或者双引号,因此很可能是因为没有双引号才导致在解析字段的时候把字符串没有当做一个整体;因此做如下测试,给varchar字段都加上双引号 “ " ”:

Hibernate: 
    update
        crawler_device 
    set
        vendor_name="魅蓝",
        vendor_url="http://product.cnmo.com/pro_sub_manu/sub_57_manu_32909_1_2.shtml",
        device_name="魅蓝Note5(64GB)",
        device_format_name="魅蓝Note5",
        os_name="Flyme 5",
        os_format_name="Flyme",
        price="停产",
        update_time="2018-08-08" 
    where
        device_url="http://product.cnmo.com/cell_phone/index1623567.shtml" 
        and id="11643"

4.3 结果

CRUD都不存在"Hibernate Space is not allowed after parameter prefix ':' "的错误,且能够正常的执行,查看数据库文件也正常;

 

 

<think>我们正在处理一个IPv6地址配置错误:"range is not allowed in a prefix"。这个错误通常发生在配置IPv6地址或前缀时,用户试图使用一个范围(例如,使用连字符“-”表示的范围)而不是一个标准的前缀表示法。 根据引用[2]和[3]提供的背景知识,我们知道IPv6地址是128位的,通常表示为8组16位的十六进制数(例如:2001:0db8:85a3:0000:0000:8a2e:0370:7334)。在配置IPv6地址或前缀时,必须遵循严格的格式。 错误信息“range is not allowed in a prefix”表明在配置前缀时使用了不允许的范围表示。在IPv6中,前缀通常用“地址/前缀长度”来表示,例如2001:db8::/32。不允许在地址或前缀中使用类似“2001:db8::1-100”这样的范围表示。 可能的原因和解决方法: 1. **错误的前缀表示**:在配置IPv6前缀时,可能错误地使用了范围(例如,使用连字符“-”来指定一个地址范围)。在IPv6中,前缀的表示应该是固定的,例如:`2001:db8:0:1::/64`。不允许使用范围。 2. **配置命令中的错误**:检查配置命令,确保没有在IPv6地址或前缀中使用连字符“-”或其他表示范围的符号。例如,在Cisco路由器上配置IPv6地址时,正确的命令是: ``` ipv6 address 2001:db8:0:1::1/64 ``` 而不是: ``` ipv6 address 2001:db8:0:1::1-100/64 # 错误,不能使用范围 ``` 3. **DHCPv6或SLAAC配置**:如果使用DHCPv6或SLAAC(无状态地址自动配置)分配地址,确保配置的前缀是标准的。例如,在配置DHCPv6池时,前缀应该以“/”后跟前缀长度表示,而不是范围。 4. **IPv6地址池配置**:在某些设备上配置IPv6地址池时,可能会要求指定一个地址范围,但此时应使用起始地址和结束地址分别指定,而不是在同一个字段中使用连字符。然而,错误信息明确指出是“prefix”(前缀)中不允许范围,所以更可能是前缀的表示错误。 5. **配置示例**:假设你正在配置一个接口的IPv6地址,正确的格式是: - 单播地址:`ipv6 address 2001:db8:1:1::1/64` - 前缀委托(如DHCPv6 PD):`ipv6 address 2001:db8:1:1::/64` 6. **验证配置**:使用命令检查配置,确保没有在IPv6地址或前缀中使用连字符“-”。如果配置中出现了类似`2001:db8::1-100`的表示,应该将其改为标准的前缀表示(如`2001:db8::/64`)或分别指定起始和结束地址(在地址池中)。 总结:错误“range is not allowed in a prefix”是因为在IPv6前缀配置中使用了范围(例如连字符“-”),而IPv6前缀必须是一个标准的CIDR表示(地址/前缀长度)。请检查配置并修正为正确的格式。 根据引用[3]中关于IPv6地址分类的提示,请确保你配置的地址类型(全局单播、唯一本地、链路本地)符合规范,并且地址格式正确。 如果问题仍然存在,请提供具体的配置命令片段,以便进一步分析。 §§相关问题§§ 1. IPv6地址的标准表示方法是什么? 2. 如何在路由器上正确配置IPv6全局单播地址? 3. IPv6地址自动配置(SLAAC)的工作原理是什么?</think>### IPv6地址配置错误:"range is not allowed in a prefix" 分析与解决 这个错误通常发生在配置IPv6地址时使用了不规范的地址范围表示法。以下是根本原因和解决方案: #### 错误原因分析 1. **非法范围符号**: - IPv6地址**不允许使用连字符(-)表示范围**(如 `2001:db8::1-100`) - 正确的前缀表示法必须是 **CIDR格式**(地址/前缀长度),例如 `2001:db8::/64` - 错误示例:`fe80::1-100/64`(含非法范围符) 2. **地址格式冲突**: - IPv6地址必须遵循 **8组4位十六进制数** 的规范(如 `2001:0db8:85a3:0000:0000:8a2e:0370:7334`) - 在自动地址配置(如EUI-64)中,MAC地址转换必须严格遵循标准[^2]: ```plaintext 00:BB:CC:DD:11:22 → 拆分 → 插入FFFE → 反转第7位 → 02BB:CCFF:FEDD:1122 ``` 3. **多播组混淆**: - 配置可能误用了多播地址(如 `FF02::1` 或 `FF02::2`)作为单播前缀[^3] - 多播地址(以 `FF` 开头)不能用于接口单播地址配置 #### 解决方案 1. **规范CIDR表示法**: ```bash # 错误配置 ipv6 address 2001:db8::1-100/64 # 正确配置(单地址) ipv6 address 2001:db8::1/64 # 正确配置(整个前缀) ipv6 address 2001:db8::/64 ``` 2. **链路本地地址修复**: - 使用EUI-64自动生成: ```bash interface GigabitEthernet0/0 ipv6 address autoconfig # 自动生成FE80::/10地址[^2] ``` - 或手动规范配置: ```bash ipv6 address fe80::1 link-local # 显式声明链路本地 ``` 3. **前缀范围验证**: - 全局单播地址:`2000::/3`(2或3开头) - 唯一本地地址:`fc00::/7`(FC或FD开头) - 链路本地地址:`fe80::/10`(FE80开头)[^3] #### 配置验证步骤 1. 检查地址格式: ```bash show ipv6 interface brief ``` 2. 确认无范围符号: ```plaintext 正确输出示例: GigabitEthernet0/0 [up/up] FE80::260:3EFF:FE11:6770 2001:DB8::1 ``` 3. 测试连通性: ```bash ping ipv6 FF02::1 # 测试链路本地多播[^3] ``` > **关键点**:IPv6地址必须严格遵循RFC 4291格式规范,任何地址范围表示都需通过子网划分实现(如 `/64` 隐含18,446,744,073,709,551,616个地址),而非显式范围声明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值